<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[196747] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/196747">196747</a></dd>
<dt>Author</dt> <dd>mmaxfield@apple.com</dd>
<dt>Date</dt> <dd>2016-02-17 23:25:56 -0800 (Wed, 17 Feb 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Font Loading] Implement FontFaceSet
https://bugs.webkit.org/show_bug.cgi?id=153348

Reviewed by Simon Fraser.

Source/WebCore:

The CSS Font Loading spec includes a FontFaceSet object which represents
a collection of FontFaces. This patch implements such an object, and
backs it with a vector of FontFaces. Similarly to the FontFace object,
FontFaceSet is separated into a FontFaceSet frontend object and a
CSSFontFaceSet backend object, which actually owns the FontFace objects.
All the interaction with Promises is performed in the frontend object.

This patch does not implement the EventTarget part of the FontFaceSet
API, so the only way to know when a font is finished loading is by using
the associated Promise objects.

The CSS Font Loading spec describes how the Document should vend an
instance of FontFaceSet which represents the font faces currently
associated with the Document. However, that functionality is
forthcoming. Currently, the only way to get a FontFaceSet is to create
one yourself (using the constructor). Therefore, this patch does not
implement the spec's notion of a &quot;CSS-connected font face.&quot;

Test: fast/text/font-face-set-javascript.html

* CMakeLists.txt: Add new files.
* DerivedSources.make: Ditto.
* WebCore.vcxproj/WebCore.vcxproj: Ditto.
* WebCore.vcxproj/WebCore.vcxproj.filters: Ditto.
* WebCore.xcodeproj/project.pbxproj: Ditto.
* bindings/js/JSFontFaceSetCustom.cpp: Added.
(WebCore::JSFontFaceSet::ready): Use the Promise member.
(WebCore::JSFontFaceSet::entries): Use existing iterator code.
(WebCore::JSFontFaceSet::keys):
(WebCore::JSFontFaceSet::values):
* css/CSSAllInOne.cpp: Add new files.
* css/CSSFontFace.cpp: We now have a collection of clients (instead of
just one). Also, we need to keep a pointer to our FontFace wrapper.
(WebCore::CSSFontFace::CSSFontFace):
(WebCore::CSSFontFace::addClient):
(WebCore::CSSFontFace::removeClient):
(WebCore::CSSFontFace::setStatus): Rename the delegate callback to be
more clear.
(WebCore::CSSFontFace::fontLoaded):
(WebCore::CSSFontFace::addedToSegmentedFontFace): Deleted.
(WebCore::CSSFontFace::removedFromSegmentedFontFace): Deleted.
* css/CSSFontFace.h: Same as above.
(WebCore::CSSFontFace::create):
(WebCore::CSSFontFace::Client::~Client):
(WebCore::CSSFontFace::Client::kick):
(WebCore::CSSFontFace::Client::stateChanged):
(WebCore::CSSFontFace::wrapper):
(WebCore::CSSFontFaceClient::~CSSFontFaceClient): Deleted.
* css/CSSFontFaceSet.cpp: Added. Initial imlementation.
(WebCore::CSSFontFaceSet::CSSFontFaceSet):
(WebCore::CSSFontFaceSet::~CSSFontFaceSet):
(WebCore::CSSFontFaceSet::incrementActiveCount):
(WebCore::CSSFontFaceSet::decrementActiveCount):
(WebCore::CSSFontFaceSet::has):
(WebCore::CSSFontFaceSet::add):
(WebCore::CSSFontFaceSet::remove):
(WebCore::extractFamilies):
(WebCore::familiesIntersect): Because this is an initial imlementation,
this function is not optimized. A subsequent patch (which implements
Document.fonts) will optimize this.
(WebCore::CSSFontFaceSet::matchingFaces):
(WebCore::CSSFontFaceSet::load):
(WebCore::CSSFontFaceSet::check):
(WebCore::CSSFontFaceSet::stateChanged):
* css/CSSFontFaceSet.h: Added.
(WebCore::CSSFontFaceSetClient::~CSSFontFaceSetClient):
(WebCore::CSSFontFaceSet::size):
(WebCore::CSSFontFaceSet::operator[]):
(WebCore::CSSFontFaceSet::status):
* css/CSSFontSelector.cpp:
(WebCore::CSSFontSelector::familyNameFromPrimitive):
(WebCore::CSSFontSelector::registerLocalFontFacesForFamily):
(WebCore::CSSFontSelector::addFontFaceRule):
(WebCore::familyNameFromPrimitive): Deleted.
(WebCore::CSSFontSelector::kick): Deleted.
* css/CSSFontSelector.h:
* css/CSSSegmentedFontFace.cpp:
(WebCore::CSSSegmentedFontFace::~CSSSegmentedFontFace):
(WebCore::CSSSegmentedFontFace::appendFontFace):
(WebCore::CSSSegmentedFontFace::kick):
(WebCore::CSSSegmentedFontFace::fontLoaded): Deleted.
* css/CSSSegmentedFontFace.h:
* css/FontFace.cpp:
(WebCore::FontFace::FontFace):
(WebCore::FontFace::~FontFace):
(WebCore::FontFace::stateChanged): Renamed to make its purpose clearer.
(WebCore::FontFace::kick): Deleted.
* css/FontFace.h:
* css/FontFaceSet.cpp: Added.
(WebCore::createPromise):
(WebCore::FontFaceSet::FontFaceSet):
(WebCore::FontFaceSet::~FontFaceSet):
(WebCore::FontFaceSet::Iterator::Iterator):
(WebCore::FontFaceSet::Iterator::next):
(WebCore::FontFaceSet::PendingPromise::PendingPromise):
(WebCore::FontFaceSet::PendingPromise::~PendingPromise):
(WebCore::FontFaceSet::has):
(WebCore::FontFaceSet::size):
(WebCore::FontFaceSet::add):
(WebCore::FontFaceSet::remove):
(WebCore::FontFaceSet::clear):
(WebCore::FontFaceSet::load): Most of the complexity of loading is
due to the promises involved. Rather than use the Javascript function
Promise.all(), this patch builds a data structure to represent the
promises which need to be resolved. When fonts finish loading, we look
at the data structure to determine which promises to resolve.
(WebCore::FontFaceSet::check):
(WebCore::FontFaceSet::status):
(WebCore::FontFaceSet::canSuspendForDocumentSuspension):
(WebCore::FontFaceSet::startedLoading):
(WebCore::FontFaceSet::completedLoading):
(WebCore::FontFaceSet::fulfillPromise): Keep the promise alive.
(WebCore::FontFaceSet::faceFinished):
* css/FontFaceSet.h: Added.
(WebCore::FontFaceSet::create):
(WebCore::FontFaceSet::load):
(WebCore::FontFaceSet::check):
(WebCore::FontFaceSet::createIterator):
(WebCore::FontFaceSet::PendingPromise::create):
* css/FontFaceSet.idl: Added.
* dom/EventNames.h:
* dom/EventTargetFactory.in:

LayoutTests:

* fast/text/font-face-set-javascript-expected.txt: Added.
* fast/text/font-face-set-javascript.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsjsdomglobalconstructorsattributesexpectedtxt">trunk/LayoutTests/js/dom/global-constructors-attributes-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformefljsdomglobalconstructorsattributesexpectedtxt">trunk/LayoutTests/platform/efl/js/dom/global-constructors-attributes-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformgtkjsdomglobalconstructorsattributesexpectedtxt">trunk/LayoutTests/platform/gtk/js/dom/global-constructors-attributes-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacjsdomglobalconstructorsattributesexpectedtxt">trunk/LayoutTests/platform/mac/js/dom/global-constructors-attributes-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacmavericksjsdomglobalconstructorsattributesexpectedtxt">trunk/LayoutTests/platform/mac-mavericks/js/dom/global-constructors-attributes-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacyosemitejsdomglobalconstructorsattributesexpectedtxt">trunk/LayoutTests/platform/mac-yosemite/js/dom/global-constructors-attributes-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformwinjsdomglobalconstructorsattributesexpectedtxt">trunk/LayoutTests/platform/win/js/dom/global-constructors-attributes-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreDerivedSourcesmake">trunk/Source/WebCore/DerivedSources.make</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxproj">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxprojfilters">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorecssCSSAllInOnecpp">trunk/Source/WebCore/css/CSSAllInOne.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSFontFacecpp">trunk/Source/WebCore/css/CSSFontFace.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSFontFaceh">trunk/Source/WebCore/css/CSSFontFace.h</a></li>
<li><a href="#trunkSourceWebCorecssCSSFontSelectorcpp">trunk/Source/WebCore/css/CSSFontSelector.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSFontSelectorh">trunk/Source/WebCore/css/CSSFontSelector.h</a></li>
<li><a href="#trunkSourceWebCorecssCSSSegmentedFontFacecpp">trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSSegmentedFontFaceh">trunk/Source/WebCore/css/CSSSegmentedFontFace.h</a></li>
<li><a href="#trunkSourceWebCorecssFontFacecpp">trunk/Source/WebCore/css/FontFace.cpp</a></li>
<li><a href="#trunkSourceWebCorecssFontFaceh">trunk/Source/WebCore/css/FontFace.h</a></li>
<li><a href="#trunkSourceWebCoredomEventNamesh">trunk/Source/WebCore/dom/EventNames.h</a></li>
<li><a href="#trunkSourceWebCoredomEventTargetFactoryin">trunk/Source/WebCore/dom/EventTargetFactory.in</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfasttextfontfacesetjavascriptexpectedtxt">trunk/LayoutTests/fast/text/font-face-set-javascript-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfasttextfontfacesetjavascripthtml">trunk/LayoutTests/fast/text/font-face-set-javascript.html</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSFontFaceSetCustomcpp">trunk/Source/WebCore/bindings/js/JSFontFaceSetCustom.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSFontFaceSetcpp">trunk/Source/WebCore/css/CSSFontFaceSet.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSFontFaceSeth">trunk/Source/WebCore/css/CSSFontFaceSet.h</a></li>
<li><a href="#trunkSourceWebCorecssFontFaceSetcpp">trunk/Source/WebCore/css/FontFaceSet.cpp</a></li>
<li><a href="#trunkSourceWebCorecssFontFaceSeth">trunk/Source/WebCore/css/FontFaceSet.h</a></li>
<li><a href="#trunkSourceWebCorecssFontFaceSetidl">trunk/Source/WebCore/css/FontFaceSet.idl</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/LayoutTests/ChangeLog        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2016-02-17  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        [Font Loading] Implement FontFaceSet
+        https://bugs.webkit.org/show_bug.cgi?id=153348
+
+        Reviewed by Simon Fraser.
+
+        * fast/text/font-face-set-javascript-expected.txt: Added.
+        * fast/text/font-face-set-javascript.html: Added.
+
</ins><span class="cx"> 2016-02-17  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r196738.
</span></span></pre></div>
<a id="trunkLayoutTestsfasttextfontfacesetjavascriptexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/text/font-face-set-javascript-expected.txt (0 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/text/font-face-set-javascript-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/text/font-face-set-javascript-expected.txt        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -0,0 +1,48 @@
</span><ins>+PASS new FontFaceSet() threw exception TypeError: Not enough arguments.
+PASS new FontFaceSet([]).size is 0
+PASS new FontFaceSet([fontFace1]).size is 1
+PASS fontFaceSet.status is &quot;loaded&quot;
+PASS item.done is false
+PASS item.value is [fontFace1, fontFace1]
+PASS item.done is true
+PASS item.done is false
+PASS item.value is fontFace1
+PASS item.done is true
+PASS item.done is false
+PASS item.value is fontFace1
+PASS item.done is true
+PASS fontFaceSet.add(fontFace2) is fontFaceSet
+PASS fontFaceSet.size is 2
+PASS item.done is false
+PASS item.value is fontFace1
+PASS item.done is false
+PASS item.value is fontFace2
+PASS item.done is true
+PASS fontFaceSet.delete(fontFace1) is true
+PASS fontFaceSet.delete(fontFace3) is false
+PASS fontFaceSet.size is 0
+PASS fontFaceSet.values().next().done is true
+PASS fontFaceSet.check('garbage') threw exception Error: SyntaxError: DOM Exception 12.
+PASS fontFaceSet.check('16px garbage') is true
+PASS fontFaceSet.check('16px family1') is false
+PASS fontFaceSet.status is &quot;loaded&quot;
+PASS item.code is item.SYNTAX_ERR
+PASS fontFaceSet.check('16px family1') is false
+PASS item is []
+PASS item.code is item.NETWORK_ERR
+PASS fontFaceSet.check('16px family3') is false
+PASS fontFaceSet.status is &quot;loading&quot;
+PASS item is [fontFace3]
+PASS fontFaceSet.check('16px family3') is true
+PASS fontFaceSet.status is &quot;loaded&quot;
+PASS fontFaceSet.status is &quot;loaded&quot;
+PASS item is [fontFace3]
+PASS item is [fontFace3, fontFace4]
+PASS item is fontFaceSet
+PASS fontFaceSet.status is &quot;loaded&quot;
+PASS fontFaceSet.status is &quot;loading&quot;
+PASS item is fontFaceSet
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins><span class="cx">Property changes on: trunk/LayoutTests/fast/text/font-face-set-javascript-expected.txt
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkLayoutTestsfasttextfontfacesetjavascripthtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/text/font-face-set-javascript.html (0 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/text/font-face-set-javascript.html                                (rev 0)
+++ trunk/LayoutTests/fast/text/font-face-set-javascript.html        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -0,0 +1,146 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+if (window.internals)
+    window.internals.clearMemoryCache();
+
+var fontFace1 = new FontFace(&quot;family1&quot;, &quot;url('asdf')&quot;, {});
+var fontFace2 = new FontFace(&quot;family2&quot;, &quot;url('asdf')&quot;, {});
+var fontFace3 = new FontFace(&quot;family3&quot;, &quot;url('../../resources/Ahem.ttf')&quot;, {});
+var fontFace4 = new FontFace(&quot;family3&quot;, &quot;url('../../resources/Ahem.ttf')&quot;, {'weight': 'bold'});
+var fontFace5 = new FontFace(&quot;family5&quot;, &quot;url('../../resources/Ahem.otf')&quot;, {});
+
+shouldThrow(&quot;new FontFaceSet()&quot;);
+shouldBe(&quot;new FontFaceSet([]).size&quot;, &quot;0&quot;);
+shouldBe(&quot;new FontFaceSet([fontFace1]).size&quot;, &quot;1&quot;);
+
+var fontFaceSet = new FontFaceSet([]);
+shouldBeEqualToString(&quot;fontFaceSet.status&quot;, &quot;loaded&quot;);
+fontFaceSet.add(fontFace1);
+var iterator = fontFaceSet.entries();
+var item = iterator.next();
+shouldBeFalse(&quot;item.done&quot;);
+shouldBe(&quot;item.value&quot;, &quot;[fontFace1, fontFace1]&quot;);
+item = iterator.next();
+shouldBeTrue(&quot;item.done&quot;);
+
+iterator = fontFaceSet.keys();
+item = iterator.next();
+shouldBeFalse(&quot;item.done&quot;);
+shouldBe(&quot;item.value&quot;, &quot;fontFace1&quot;);
+item = iterator.next();
+shouldBeTrue(&quot;item.done&quot;);
+
+iterator = fontFaceSet.values();
+item = iterator.next();
+shouldBeFalse(&quot;item.done&quot;);
+shouldBe(&quot;item.value&quot;, &quot;fontFace1&quot;);
+item = iterator.next();
+shouldBeTrue(&quot;item.done&quot;);
+
+shouldBe(&quot;fontFaceSet.add(fontFace2)&quot;, &quot;fontFaceSet&quot;);
+shouldBe(&quot;fontFaceSet.size&quot;, &quot;2&quot;);
+
+iterator = fontFaceSet.keys();
+item = iterator.next();
+shouldBeFalse(&quot;item.done&quot;);
+shouldBe(&quot;item.value&quot;, &quot;fontFace1&quot;);
+item = iterator.next();
+shouldBeFalse(&quot;item.done&quot;);
+shouldBe(&quot;item.value&quot;, &quot;fontFace2&quot;);
+item = iterator.next();
+shouldBeTrue(&quot;item.done&quot;);
+
+shouldBe(&quot;fontFaceSet.delete(fontFace1)&quot;, &quot;true&quot;);
+shouldBe(&quot;fontFaceSet.delete(fontFace3)&quot;, &quot;false&quot;);
+fontFaceSet.clear();
+shouldBe(&quot;fontFaceSet.size&quot;, &quot;0&quot;);
+shouldBeTrue(&quot;fontFaceSet.values().next().done&quot;);
+shouldThrow(&quot;fontFaceSet.check('garbage')&quot;);
+shouldBeTrue(&quot;fontFaceSet.check('16px garbage')&quot;);
+
+self.jsTestIsAsync = true;
+fontFaceSet.add(fontFace1);
+shouldBeFalse(&quot;fontFaceSet.check('16px family1')&quot;);
+var item;
+fontFaceSet.load(&quot;garbage&quot;).then(function(arg) {
+    testFailed(&quot;Should not be able to parse garbage&quot;);
+    finishJSTest();
+}, function(arg) {
+    item = arg;
+    shouldBe(&quot;item.code&quot;, &quot;item.SYNTAX_ERR&quot;);
+    shouldBeFalse(&quot;fontFaceSet.check('16px family1')&quot;);
+    return fontFaceSet.load(&quot;16px garbage&quot;);
+}).then(function(arg) {
+    item = arg;
+    shouldBe(&quot;item&quot;, &quot;[]&quot;);
+    return fontFaceSet.load(&quot;16px family1&quot;);
+}, function(arg) {
+    testFailed(&quot;Should not be able to parse garbage&quot;);
+    finishJSTest();
+}).then(function(arg) {
+    testFailed(&quot;Bogus URL should not load&quot;);
+    finishJSTest();
+}, function(arg) {
+    item = arg;
+    shouldBe(&quot;item.code&quot;, &quot;item.NETWORK_ERR&quot;);
+    fontFaceSet.add(fontFace3);
+    shouldBeFalse(&quot;fontFaceSet.check('16px family3')&quot;);
+    var result = fontFaceSet.load(&quot;16px family3&quot;);
+    shouldBeEqualToString(&quot;fontFaceSet.status&quot;, &quot;loading&quot;);
+    return result;
+}).then(function(arg) {
+    item = arg;
+    shouldBe(&quot;item&quot;, &quot;[fontFace3]&quot;);
+    shouldBeTrue(&quot;fontFaceSet.check('16px family3')&quot;);
+    shouldBeEqualToString(&quot;fontFaceSet.status&quot;, &quot;loaded&quot;);
+    var result = fontFaceSet.load(&quot;16px family3&quot;); // Test when it's in the cache.
+    shouldBeEqualToString(&quot;fontFaceSet.status&quot;, &quot;loaded&quot;);
+    return result;
+}, function(arg) {
+    testFailed(&quot;Real URL should load&quot;);
+    finishJSTest();
+}).then(function(arg) {
+    item = arg;
+    shouldBe(&quot;item&quot;, &quot;[fontFace3]&quot;);
+    fontFaceSet.add(fontFace4);
+    return fontFaceSet.load(&quot;16px family3&quot;);
+}, function(arg) {
+    testFailed(&quot;Real URL should load&quot;);
+    finishJSTest();
+}).then(function(arg) {
+    item = arg;
+    shouldBe(&quot;item&quot;, &quot;[fontFace3, fontFace4]&quot;);
+    fontFaceSet.add(fontFace4);
+    fontFaceSet.load(&quot;16px family3&quot;);
+    return fontFaceSet.ready;
+}, function(arg) {
+    testFailed(&quot;Multiple matching faces should load&quot;);
+    finishJSTest();
+}).then(function(arg) {
+    item = arg;
+    shouldBe(&quot;item&quot;, &quot;fontFaceSet&quot;);
+    fontFaceSet.add(fontFace5);
+    shouldBeEqualToString(&quot;fontFaceSet.status&quot;, &quot;loaded&quot;);
+    fontFaceSet.load(&quot;16px family5&quot;);
+    shouldBeEqualToString(&quot;fontFaceSet.status&quot;, &quot;loading&quot;);
+    return fontFaceSet.ready;
+}, function(arg) {
+    testFailed(&quot;Ready attribute should never fail&quot;);
+    finishJSTest();
+}).then(function(arg) {
+    item = arg;
+    shouldBe(&quot;item&quot;, &quot;fontFaceSet&quot;);
+    finishJSTest();
+}, function(arg) {
+    testFailed(&quot;Ready attribute should never fail&quot;);
+    finishJSTest();
+});
+shouldBeEqualToString(&quot;fontFaceSet.status&quot;, &quot;loaded&quot;);
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsdomglobalconstructorsattributesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/dom/global-constructors-attributes-expected.txt (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/global-constructors-attributes-expected.txt        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/LayoutTests/js/dom/global-constructors-attributes-expected.txt        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -378,6 +378,11 @@
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').hasOwnProperty('set') is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').enumerable is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').configurable is true
</span><ins>+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').value is FontFaceSet
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').configurable is true
</ins><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').value is FormData
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').hasOwnProperty('get') is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').hasOwnProperty('set') is false
</span></span></pre></div>
<a id="trunkLayoutTestsplatformefljsdomglobalconstructorsattributesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/efl/js/dom/global-constructors-attributes-expected.txt (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/efl/js/dom/global-constructors-attributes-expected.txt        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/LayoutTests/platform/efl/js/dom/global-constructors-attributes-expected.txt        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -373,6 +373,11 @@
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').hasOwnProperty('set') is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').enumerable is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').configurable is true
</span><ins>+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').value is FontFaceSet
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').configurable is true
</ins><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').value is FormData
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').hasOwnProperty('get') is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').hasOwnProperty('set') is false
</span></span></pre></div>
<a id="trunkLayoutTestsplatformgtkjsdomglobalconstructorsattributesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/gtk/js/dom/global-constructors-attributes-expected.txt (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/gtk/js/dom/global-constructors-attributes-expected.txt        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/LayoutTests/platform/gtk/js/dom/global-constructors-attributes-expected.txt        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -378,6 +378,11 @@
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').hasOwnProperty('set') is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').enumerable is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').configurable is true
</span><ins>+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').value is FontFaceSet
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').configurable is true
</ins><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').value is FormData
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').hasOwnProperty('get') is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').hasOwnProperty('set') is false
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacjsdomglobalconstructorsattributesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/js/dom/global-constructors-attributes-expected.txt (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/js/dom/global-constructors-attributes-expected.txt        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/LayoutTests/platform/mac/js/dom/global-constructors-attributes-expected.txt        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -423,6 +423,11 @@
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').hasOwnProperty('set') is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').enumerable is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').configurable is true
</span><ins>+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').value is FontFaceSet
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').configurable is true
</ins><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').value is FormData
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').hasOwnProperty('get') is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').hasOwnProperty('set') is false
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacmavericksjsdomglobalconstructorsattributesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac-mavericks/js/dom/global-constructors-attributes-expected.txt (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-mavericks/js/dom/global-constructors-attributes-expected.txt        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/LayoutTests/platform/mac-mavericks/js/dom/global-constructors-attributes-expected.txt        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -378,6 +378,11 @@
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').hasOwnProperty('set') is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').enumerable is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').configurable is true
</span><ins>+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').value is FontFaceSet
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').configurable is true
</ins><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').value is FormData
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').hasOwnProperty('get') is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').hasOwnProperty('set') is false
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacyosemitejsdomglobalconstructorsattributesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac-yosemite/js/dom/global-constructors-attributes-expected.txt (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-yosemite/js/dom/global-constructors-attributes-expected.txt        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/LayoutTests/platform/mac-yosemite/js/dom/global-constructors-attributes-expected.txt        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -423,6 +423,11 @@
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').hasOwnProperty('set') is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').enumerable is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').configurable is true
</span><ins>+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').value is FontFaceSet
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').configurable is true
</ins><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').value is FormData
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').hasOwnProperty('get') is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').hasOwnProperty('set') is false
</span></span></pre></div>
<a id="trunkLayoutTestsplatformwinjsdomglobalconstructorsattributesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/win/js/dom/global-constructors-attributes-expected.txt (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/win/js/dom/global-constructors-attributes-expected.txt        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/LayoutTests/platform/win/js/dom/global-constructors-attributes-expected.txt        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -298,6 +298,11 @@
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').hasOwnProperty('set') is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').enumerable is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FontFace').configurable is true
</span><ins>+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').value is FontFaceSet
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'FontFaceSet').configurable is true
</ins><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').value is FormData
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').hasOwnProperty('get') is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(global, 'FormData').hasOwnProperty('set') is false
</span></span></pre></div>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/Source/WebCore/CMakeLists.txt        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -331,6 +331,7 @@
</span><span class="cx">     css/Counter.idl
</span><span class="cx">     css/DOMWindowCSS.idl
</span><span class="cx">     css/FontFace.idl
</span><ins>+    css/FontFaceSet.idl
</ins><span class="cx">     css/FontLoader.idl
</span><span class="cx">     css/MediaList.idl
</span><span class="cx">     css/MediaQueryList.idl
</span><span class="lines">@@ -1110,6 +1111,7 @@
</span><span class="cx">     bindings/js/JSCSSRuleListCustom.cpp
</span><span class="cx">     bindings/js/JSCSSStyleDeclarationCustom.cpp
</span><span class="cx">     bindings/js/JSFontFaceCustom.cpp
</span><ins>+    bindings/js/JSFontFaceSetCustom.cpp
</ins><span class="cx">     bindings/js/JSCSSValueCustom.cpp
</span><span class="cx">     bindings/js/JSCallbackData.cpp
</span><span class="cx">     bindings/js/JSCanvasRenderingContext2DCustom.cpp
</span><span class="lines">@@ -1302,8 +1304,10 @@
</span><span class="cx">     css/CSSCursorImageValue.cpp
</span><span class="cx">     css/CSSDefaultStyleSheets.cpp
</span><span class="cx">     css/CSSFilterImageValue.cpp
</span><ins>+    css/FontFaceSet.cpp
</ins><span class="cx">     css/FontFace.cpp
</span><span class="cx">     css/CSSFontFace.cpp
</span><ins>+    css/CSSFontFaceSet.cpp
</ins><span class="cx">     css/CSSFontFaceLoadEvent.cpp
</span><span class="cx">     css/CSSFontFaceRule.cpp
</span><span class="cx">     css/CSSFontFaceSource.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/Source/WebCore/ChangeLog        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -1,3 +1,133 @@
</span><ins>+2016-02-17  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        [Font Loading] Implement FontFaceSet
+        https://bugs.webkit.org/show_bug.cgi?id=153348
+
+        Reviewed by Simon Fraser.
+
+        The CSS Font Loading spec includes a FontFaceSet object which represents
+        a collection of FontFaces. This patch implements such an object, and
+        backs it with a vector of FontFaces. Similarly to the FontFace object,
+        FontFaceSet is separated into a FontFaceSet frontend object and a
+        CSSFontFaceSet backend object, which actually owns the FontFace objects.
+        All the interaction with Promises is performed in the frontend object.
+
+        This patch does not implement the EventTarget part of the FontFaceSet
+        API, so the only way to know when a font is finished loading is by using
+        the associated Promise objects.
+
+        The CSS Font Loading spec describes how the Document should vend an
+        instance of FontFaceSet which represents the font faces currently
+        associated with the Document. However, that functionality is
+        forthcoming. Currently, the only way to get a FontFaceSet is to create
+        one yourself (using the constructor). Therefore, this patch does not
+        implement the spec's notion of a &quot;CSS-connected font face.&quot;
+
+        Test: fast/text/font-face-set-javascript.html
+
+        * CMakeLists.txt: Add new files.
+        * DerivedSources.make: Ditto.
+        * WebCore.vcxproj/WebCore.vcxproj: Ditto.
+        * WebCore.vcxproj/WebCore.vcxproj.filters: Ditto.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+        * bindings/js/JSFontFaceSetCustom.cpp: Added.
+        (WebCore::JSFontFaceSet::ready): Use the Promise member.
+        (WebCore::JSFontFaceSet::entries): Use existing iterator code.
+        (WebCore::JSFontFaceSet::keys):
+        (WebCore::JSFontFaceSet::values):
+        * css/CSSAllInOne.cpp: Add new files.
+        * css/CSSFontFace.cpp: We now have a collection of clients (instead of
+        just one). Also, we need to keep a pointer to our FontFace wrapper.
+        (WebCore::CSSFontFace::CSSFontFace):
+        (WebCore::CSSFontFace::addClient):
+        (WebCore::CSSFontFace::removeClient):
+        (WebCore::CSSFontFace::setStatus): Rename the delegate callback to be
+        more clear.
+        (WebCore::CSSFontFace::fontLoaded):
+        (WebCore::CSSFontFace::addedToSegmentedFontFace): Deleted.
+        (WebCore::CSSFontFace::removedFromSegmentedFontFace): Deleted.
+        * css/CSSFontFace.h: Same as above.
+        (WebCore::CSSFontFace::create):
+        (WebCore::CSSFontFace::Client::~Client):
+        (WebCore::CSSFontFace::Client::kick):
+        (WebCore::CSSFontFace::Client::stateChanged):
+        (WebCore::CSSFontFace::wrapper):
+        (WebCore::CSSFontFaceClient::~CSSFontFaceClient): Deleted.
+        * css/CSSFontFaceSet.cpp: Added. Initial imlementation.
+        (WebCore::CSSFontFaceSet::CSSFontFaceSet):
+        (WebCore::CSSFontFaceSet::~CSSFontFaceSet):
+        (WebCore::CSSFontFaceSet::incrementActiveCount):
+        (WebCore::CSSFontFaceSet::decrementActiveCount):
+        (WebCore::CSSFontFaceSet::has):
+        (WebCore::CSSFontFaceSet::add):
+        (WebCore::CSSFontFaceSet::remove):
+        (WebCore::extractFamilies):
+        (WebCore::familiesIntersect): Because this is an initial imlementation,
+        this function is not optimized. A subsequent patch (which implements
+        Document.fonts) will optimize this.
+        (WebCore::CSSFontFaceSet::matchingFaces):
+        (WebCore::CSSFontFaceSet::load):
+        (WebCore::CSSFontFaceSet::check):
+        (WebCore::CSSFontFaceSet::stateChanged):
+        * css/CSSFontFaceSet.h: Added.
+        (WebCore::CSSFontFaceSetClient::~CSSFontFaceSetClient):
+        (WebCore::CSSFontFaceSet::size):
+        (WebCore::CSSFontFaceSet::operator[]):
+        (WebCore::CSSFontFaceSet::status):
+        * css/CSSFontSelector.cpp:
+        (WebCore::CSSFontSelector::familyNameFromPrimitive):
+        (WebCore::CSSFontSelector::registerLocalFontFacesForFamily):
+        (WebCore::CSSFontSelector::addFontFaceRule):
+        (WebCore::familyNameFromPrimitive): Deleted.
+        (WebCore::CSSFontSelector::kick): Deleted.
+        * css/CSSFontSelector.h:
+        * css/CSSSegmentedFontFace.cpp:
+        (WebCore::CSSSegmentedFontFace::~CSSSegmentedFontFace):
+        (WebCore::CSSSegmentedFontFace::appendFontFace):
+        (WebCore::CSSSegmentedFontFace::kick):
+        (WebCore::CSSSegmentedFontFace::fontLoaded): Deleted.
+        * css/CSSSegmentedFontFace.h:
+        * css/FontFace.cpp:
+        (WebCore::FontFace::FontFace):
+        (WebCore::FontFace::~FontFace):
+        (WebCore::FontFace::stateChanged): Renamed to make its purpose clearer.
+        (WebCore::FontFace::kick): Deleted.
+        * css/FontFace.h:
+        * css/FontFaceSet.cpp: Added.
+        (WebCore::createPromise):
+        (WebCore::FontFaceSet::FontFaceSet):
+        (WebCore::FontFaceSet::~FontFaceSet):
+        (WebCore::FontFaceSet::Iterator::Iterator):
+        (WebCore::FontFaceSet::Iterator::next):
+        (WebCore::FontFaceSet::PendingPromise::PendingPromise):
+        (WebCore::FontFaceSet::PendingPromise::~PendingPromise):
+        (WebCore::FontFaceSet::has):
+        (WebCore::FontFaceSet::size):
+        (WebCore::FontFaceSet::add):
+        (WebCore::FontFaceSet::remove):
+        (WebCore::FontFaceSet::clear):
+        (WebCore::FontFaceSet::load): Most of the complexity of loading is
+        due to the promises involved. Rather than use the Javascript function
+        Promise.all(), this patch builds a data structure to represent the
+        promises which need to be resolved. When fonts finish loading, we look
+        at the data structure to determine which promises to resolve.
+        (WebCore::FontFaceSet::check):
+        (WebCore::FontFaceSet::status):
+        (WebCore::FontFaceSet::canSuspendForDocumentSuspension):
+        (WebCore::FontFaceSet::startedLoading):
+        (WebCore::FontFaceSet::completedLoading):
+        (WebCore::FontFaceSet::fulfillPromise): Keep the promise alive.
+        (WebCore::FontFaceSet::faceFinished):
+        * css/FontFaceSet.h: Added.
+        (WebCore::FontFaceSet::create):
+        (WebCore::FontFaceSet::load):
+        (WebCore::FontFaceSet::check):
+        (WebCore::FontFaceSet::createIterator):
+        (WebCore::FontFaceSet::PendingPromise::create):
+        * css/FontFaceSet.idl: Added.
+        * dom/EventNames.h:
+        * dom/EventTargetFactory.in:
+
</ins><span class="cx"> 2016-02-17  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Callers of JSString::value() should check for exceptions thereafter.
</span></span></pre></div>
<a id="trunkSourceWebCoreDerivedSourcesmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/DerivedSources.make (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/DerivedSources.make        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/Source/WebCore/DerivedSources.make        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -242,6 +242,7 @@
</span><span class="cx">     $(WebCore)/css/Counter.idl \
</span><span class="cx">     $(WebCore)/css/DOMWindowCSS.idl \
</span><span class="cx">     $(WebCore)/css/FontFace.idl \
</span><ins>+    $(WebCore)/css/FontFaceSet.idl \
</ins><span class="cx">     $(WebCore)/css/FontLoader.idl \
</span><span class="cx">     $(WebCore)/css/MediaList.idl \
</span><span class="cx">     $(WebCore)/css/MediaQueryList.idl \
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -1971,6 +1971,20 @@
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Release|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='DebugSuffix|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><ins>+    &lt;ClCompile Include=&quot;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSFontFaceSet.cpp&quot;&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='DebugSuffix|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Release|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Release|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Production|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Production|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+    &lt;/ClCompile&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSFontFace.cpp&quot;&gt;
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="lines">@@ -9611,6 +9625,20 @@
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Production|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Production|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\css\FontFaceSet.cpp&quot;&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='DebugSuffix|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Release|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Release|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Production|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Production|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+    &lt;/ClCompile&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\css\FontFace.cpp&quot;&gt;
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="lines">@@ -9625,6 +9653,20 @@
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Production|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Production|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\css\CSSFontFaceSet.cpp&quot;&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='DebugSuffix|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Release|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Release|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Production|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Production|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+    &lt;/ClCompile&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\css\CSSFontFace.cpp&quot;&gt;
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="lines">@@ -17740,6 +17782,20 @@
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Production|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Production|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\bindings\js\JSFontFaceSetCustom.cpp&quot;&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='DebugSuffix|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Release|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Release|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Production|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+      &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Production|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
+    &lt;/ClCompile&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\bindings\js\JSFontFaceCustom.cpp&quot;&gt;
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="lines">@@ -19987,6 +20043,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSFileReader.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSFileReaderSync.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSFontLoader.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSFontFaceSet.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSFontFace.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSGamepad.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSGamepadButton.h&quot; /&gt;
</span><span class="lines">@@ -21705,7 +21762,9 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\css\CSSCursorImageValue.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\css\CSSFilterImageValue.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\css\CSSFontFace.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\css\CSSFontFaceSet.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\css\FontFace.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\css\FontFaceSet.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\css\CSSFontFaceLoadEvent.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\css\CSSFontFaceRule.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\css\CSSFontFaceSource.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -2084,9 +2084,15 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\css\CSSCursorImageValue.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;css&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\css\FontFaceSet.cpp&quot;&gt;
+      &lt;Filter&gt;css&lt;/Filter&gt;
+    &lt;/ClCompile&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\css\FontFace.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;css&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\css\CSSFontFaceSet.cpp&quot;&gt;
+      &lt;Filter&gt;css&lt;/Filter&gt;
+    &lt;/ClCompile&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\css\CSSFontFace.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;css&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><span class="lines">@@ -4262,6 +4268,9 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bindings\js\JSCSSRuleListCustom.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;bindings\js&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\bindings\js\JSFontFaceSetCustom.cpp&quot;&gt;
+      &lt;Filter&gt;bindings\js&lt;/Filter&gt;
+    &lt;/ClCompile&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\bindings\js\JSFontFaceCustom.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;bindings\js&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><span class="lines">@@ -5274,6 +5283,9 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSFileReaderSync.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;DerivedSources&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><ins>+    &lt;ClCompile Include=&quot;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSFontFaceSet.cpp&quot;&gt;
+      &lt;Filter&gt;DerivedSources&lt;/Filter&gt;
+    &lt;/ClCompile&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSFontFace.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;DerivedSources&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><span class="lines">@@ -9067,9 +9079,15 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\css\CSSCursorImageValue.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;css&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\css\FontFaceSet.h&quot;&gt;
+      &lt;Filter&gt;css&lt;/Filter&gt;
+    &lt;/ClInclude&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\css\FontFace.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;css&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\css\CSSFontFaceSet.h&quot;&gt;
+      &lt;Filter&gt;css&lt;/Filter&gt;
+    &lt;/ClInclude&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\css\CSSFontFace.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;css&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><span class="lines">@@ -12702,6 +12720,9 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSFileReaderSync.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;DerivedSources&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><ins>+    &lt;ClInclude Include=&quot;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSFontFaceSet.h&quot;&gt;
+      &lt;Filter&gt;DerivedSources&lt;/Filter&gt;
+    &lt;/ClInclude&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSFontFace.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;DerivedSources&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -950,6 +950,11 @@
</span><span class="cx">                 1C21E57C183ED1FF001C289D /* IOSurfacePool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C21E57A183ED1FF001C289D /* IOSurfacePool.cpp */; };
</span><span class="cx">                 1C21E57D183ED1FF001C289D /* IOSurfacePool.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C21E57B183ED1FF001C289D /* IOSurfacePool.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 1C2417BA1992C04100EF9938 /* SpellingDot@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1C2417B91992C04100EF9938 /* SpellingDot@3x.png */; };
</span><ins>+                1C24EEA41C729CE40080F8FC /* FontFaceSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C24EEA21C729CE40080F8FC /* FontFaceSet.cpp */; };
+                1C24EEA51C729CE40080F8FC /* FontFaceSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C24EEA31C729CE40080F8FC /* FontFaceSet.h */; };
+                1C24EEA81C72A7B40080F8FC /* JSFontFaceSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C24EEA61C72A7B40080F8FC /* JSFontFaceSet.cpp */; };
+                1C24EEA91C72A7B40080F8FC /* JSFontFaceSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C24EEA71C72A7B40080F8FC /* JSFontFaceSet.h */; };
+                1C24EEAB1C72AA0A0080F8FC /* JSFontFaceSetCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C24EEAA1C72AA0A0080F8FC /* JSFontFaceSetCustom.cpp */; };
</ins><span class="cx">                 1C26497A0D7E248A00BD10F2 /* DocumentLoaderMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C2649790D7E248A00BD10F2 /* DocumentLoaderMac.cpp */; };
</span><span class="cx">                 1C3249111C6D6A3B007EDB32 /* FontVariantBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C3249101C6D6A3B007EDB32 /* FontVariantBuilder.cpp */; };
</span><span class="cx">                 1C3969D01B74211E002BCFA7 /* FontCacheCoreText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C3969CF1B74211E002BCFA7 /* FontCacheCoreText.cpp */; };
</span><span class="lines">@@ -5915,6 +5920,8 @@
</span><span class="cx">                 C105DA620F3AA68F001DD44F /* TextEncodingDetectorICU.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C105DA610F3AA68F001DD44F /* TextEncodingDetectorICU.cpp */; };
</span><span class="cx">                 C105DA640F3AA6B8001DD44F /* TextEncodingDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = C105DA630F3AA6B8001DD44F /* TextEncodingDetector.h */; };
</span><span class="cx">                 C2015C0A1BE6FEB200822389 /* FontVariantBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = C2015C091BE6FE2C00822389 /* FontVariantBuilder.h */; };
</span><ins>+                C26017A31C72DC9900F74A16 /* CSSFontFaceSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C26017A11C72DC9900F74A16 /* CSSFontFaceSet.cpp */; };
+                C26017A41C72DC9900F74A16 /* CSSFontFaceSet.h in Headers */ = {isa = PBXBuildFile; fileRef = C26017A21C72DC9900F74A16 /* CSSFontFaceSet.h */; };
</ins><span class="cx">                 C280833F1C6DC26F001451B6 /* JSFontFace.h in Headers */ = {isa = PBXBuildFile; fileRef = C280833E1C6DC22C001451B6 /* JSFontFace.h */; };
</span><span class="cx">                 C28083401C6DC275001451B6 /* JSFontFace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C280833D1C6DC22C001451B6 /* JSFontFace.cpp */; };
</span><span class="cx">                 C28083421C6DC96A001451B6 /* JSFontFaceCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C28083411C6DC96A001451B6 /* JSFontFaceCustom.cpp */; };
</span><span class="lines">@@ -8376,6 +8383,12 @@
</span><span class="cx">                 1C21E57A183ED1FF001C289D /* IOSurfacePool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IOSurfacePool.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 1C21E57B183ED1FF001C289D /* IOSurfacePool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IOSurfacePool.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 1C2417B91992C04100EF9938 /* SpellingDot@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = &quot;SpellingDot@3x.png&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                1C24EEA11C729B320080F8FC /* FontFaceSet.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = FontFaceSet.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
+                1C24EEA21C729CE40080F8FC /* FontFaceSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontFaceSet.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                1C24EEA31C729CE40080F8FC /* FontFaceSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontFaceSet.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                1C24EEA61C72A7B40080F8FC /* JSFontFaceSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFontFaceSet.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                1C24EEA71C72A7B40080F8FC /* JSFontFaceSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFontFaceSet.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                1C24EEAA1C72AA0A0080F8FC /* JSFontFaceSetCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFontFaceSetCustom.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 1C2649790D7E248A00BD10F2 /* DocumentLoaderMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentLoaderMac.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 1C3249101C6D6A3B007EDB32 /* FontVariantBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontVariantBuilder.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 1C3969CF1B74211E002BCFA7 /* FontCacheCoreText.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontCacheCoreText.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -13837,6 +13850,8 @@
</span><span class="cx">                 C105DA630F3AA6B8001DD44F /* TextEncodingDetector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextEncodingDetector.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C2015C091BE6FE2C00822389 /* FontVariantBuilder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FontVariantBuilder.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C24685131A148E1800811792 /* CoreGraphicsSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoreGraphicsSPI.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                C26017A11C72DC9900F74A16 /* CSSFontFaceSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSFontFaceSet.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                C26017A21C72DC9900F74A16 /* CSSFontFaceSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSFontFaceSet.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 C280833C1C6DB194001451B6 /* FontFace.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = FontFace.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C280833D1C6DC22C001451B6 /* JSFontFace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFontFace.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C280833E1C6DC22C001451B6 /* JSFontFace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFontFace.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -17561,6 +17576,8 @@
</span><span class="cx">                 656580EC09D12B20000E61D7 /* Derived Sources */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                1C24EEA61C72A7B40080F8FC /* JSFontFaceSet.cpp */,
+                                1C24EEA71C72A7B40080F8FC /* JSFontFaceSet.h */,
</ins><span class="cx">                                 C280833D1C6DC22C001451B6 /* JSFontFace.cpp */,
</span><span class="cx">                                 C280833E1C6DC22C001451B6 /* JSFontFace.h */,
</span><span class="cx">                                 9908B0F31BCACFFE00ED0F65 /* ByteLengthQueuingStrategyBuiltins.cpp */,
</span><span class="lines">@@ -22471,6 +22488,7 @@
</span><span class="cx">                                 A1C7FAA1133A5D3500D6732D /* JSXPathResultCustom.cpp */,
</span><span class="cx">                                 BCEFE1E40DCA5F3300739219 /* JSXSLTProcessorCustom.cpp */,
</span><span class="cx">                                 C28083411C6DC96A001451B6 /* JSFontFaceCustom.cpp */,
</span><ins>+                                1C24EEAA1C72AA0A0080F8FC /* JSFontFaceSetCustom.cpp */,
</ins><span class="cx">                         );
</span><span class="cx">                         name = Custom;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -23780,6 +23798,11 @@
</span><span class="cx">                                 1C66260E1C6E7CA600AB527C /* FontFace.cpp */,
</span><span class="cx">                                 1C66260F1C6E7CA600AB527C /* FontFace.h */,
</span><span class="cx">                                 C280833C1C6DB194001451B6 /* FontFace.idl */,
</span><ins>+                                1C24EEA11C729B320080F8FC /* FontFaceSet.idl */,
+                                1C24EEA21C729CE40080F8FC /* FontFaceSet.cpp */,
+                                1C24EEA31C729CE40080F8FC /* FontFaceSet.h */,
+                                C26017A11C72DC9900F74A16 /* CSSFontFaceSet.cpp */,
+                                C26017A21C72DC9900F74A16 /* CSSFontFaceSet.h */,
</ins><span class="cx">                         );
</span><span class="cx">                         path = css;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -26502,6 +26525,7 @@
</span><span class="cx">                                 0FDA7C1F188322FC00C954B5 /* JSGestureEvent.h in Headers */,
</span><span class="cx">                                 8482B7521198CB6B00BFB005 /* JSHashChangeEvent.h in Headers */,
</span><span class="cx">                                 BC94D14F0C275C68006BC617 /* JSHistory.h in Headers */,
</span><ins>+                                1C24EEA51C729CE40080F8FC /* FontFaceSet.h in Headers */,
</ins><span class="cx">                                 BC97E413109154FA0010D361 /* JSHTMLAllCollection.h in Headers */,
</span><span class="cx">                                 1A4A2DF00A1B852A00C807F8 /* JSHTMLAnchorElement.h in Headers */,
</span><span class="cx">                                 1A4A2DF20A1B852A00C807F8 /* JSHTMLAppletElement.h in Headers */,
</span><span class="lines">@@ -27315,6 +27339,7 @@
</span><span class="cx">                                 BC76AC130DD7AD5C00415F34 /* ParserUtilities.h in Headers */,
</span><span class="cx">                                 536D5A23193E8E0C00CE4CAB /* ParsingUtilities.h in Headers */,
</span><span class="cx">                                 F55B3DCA1251F12D003EF269 /* PasswordInputType.h in Headers */,
</span><ins>+                                1C24EEA91C72A7B40080F8FC /* JSFontFaceSet.h in Headers */,
</ins><span class="cx">                                 4B2708C70AF19EE40065127F /* Pasteboard.h in Headers */,
</span><span class="cx">                                 C598905714E9C28000E8D18B /* PasteboardStrategy.h in Headers */,
</span><span class="cx">                                 B27535800B053814002CE64F /* Path.h in Headers */,
</span><span class="lines">@@ -28050,6 +28075,7 @@
</span><span class="cx">                                 0810764412828556007C63BA /* SVGListProperty.h in Headers */,
</span><span class="cx">                                 088A0E09126EF1DB00978F7A /* SVGListPropertyTearOff.h in Headers */,
</span><span class="cx">                                 B2227A410D00BF220071B782 /* SVGLocatable.h in Headers */,
</span><ins>+                                C26017A41C72DC9900F74A16 /* CSSFontFaceSet.h in Headers */,
</ins><span class="cx">                                 436708EE12D9CA4B00044234 /* SVGMarkerData.h in Headers */,
</span><span class="cx">                                 B2227A440D00BF220071B782 /* SVGMarkerElement.h in Headers */,
</span><span class="cx">                                 B2227A470D00BF220071B782 /* SVGMaskElement.h in Headers */,
</span><span class="lines">@@ -29870,6 +29896,7 @@
</span><span class="cx">                                 51E1ECC00C91C90400DC255B /* IconRecord.cpp in Sources */,
</span><span class="cx">                                 5185FC771BB4C4E80012898F /* IDBAny.cpp in Sources */,
</span><span class="cx">                                 5198F7BE1BC338AF00E2CC5F /* IDBAnyImpl.cpp in Sources */,
</span><ins>+                                C26017A31C72DC9900F74A16 /* CSSFontFaceSet.cpp in Sources */,
</ins><span class="cx">                                 C585A66211D4FAC5004C3E4B /* IDBBindingUtilities.cpp in Sources */,
</span><span class="cx">                                 516D7D711BB5F0BD00AF7C77 /* IDBConnectionToClient.cpp in Sources */,
</span><span class="cx">                                 5198F7C01BC4856700E2CC5F /* IDBConnectionToServer.cpp in Sources */,
</span><span class="lines">@@ -30395,6 +30422,7 @@
</span><span class="cx">                                 1A0D57400A5C7867007EDD4C /* JSOverflowEvent.cpp in Sources */,
</span><span class="cx">                                 E1284BB210449FFA00EAEB52 /* JSPageTransitionEvent.cpp in Sources */,
</span><span class="cx">                                 FDA15EB112B03EE1003A583A /* JSPannerNode.cpp in Sources */,
</span><ins>+                                1C24EEA41C729CE40080F8FC /* FontFaceSet.cpp in Sources */,
</ins><span class="cx">                                 FD8AA63E169514A700D2EA68 /* JSPannerNodeCustom.cpp in Sources */,
</span><span class="cx">                                 E51A81DF17298D7700BFCA61 /* JSPerformance.cpp in Sources */,
</span><span class="cx">                                 8A9A587011E84C36008ACFD1 /* JSPerformanceNavigation.cpp in Sources */,
</span><span class="lines">@@ -31165,6 +31193,7 @@
</span><span class="cx">                                 ABDDFE790A5C6E7000A3E11D /* RenderMenuList.cpp in Sources */,
</span><span class="cx">                                 A454424E119B3687009BE912 /* RenderMeter.cpp in Sources */,
</span><span class="cx">                                 1A3586DF15264C450022A659 /* RenderMultiColumnFlowThread.cpp in Sources */,
</span><ins>+                                1C24EEA81C72A7B40080F8FC /* JSFontFaceSet.cpp in Sources */,
</ins><span class="cx">                                 BCE32B9E1517C22700F542EC /* RenderMultiColumnSet.cpp in Sources */,
</span><span class="cx">                                 BC1A7D9718FCB5B000421879 /* RenderMultiColumnSpannerPlaceholder.cpp in Sources */,
</span><span class="cx">                                 8AC822FC180FC03300FB64D5 /* RenderNamedFlowFragment.cpp in Sources */,
</span><span class="lines">@@ -31586,6 +31615,7 @@
</span><span class="cx">                                 511EC12B1C50ABBF0032F983 /* SQLiteIDBTransaction.cpp in Sources */,
</span><span class="cx">                                 845E72FB0FD2623900A87D79 /* SVGFilter.cpp in Sources */,
</span><span class="cx">                                 081EBF3A0FD34F4100DA7559 /* SVGFilterBuilder.cpp in Sources */,
</span><ins>+                                1C24EEAB1C72AA0A0080F8FC /* JSFontFaceSetCustom.cpp in Sources */,
</ins><span class="cx">                                 B2227A0B0D00BF220071B782 /* SVGFilterElement.cpp in Sources */,
</span><span class="cx">                                 B2227A0E0D00BF220071B782 /* SVGFilterPrimitiveStandardAttributes.cpp in Sources */,
</span><span class="cx">                                 B2227A110D00BF220071B782 /* SVGFitToViewBox.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSFontFaceSetCustomcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/bindings/js/JSFontFaceSetCustom.cpp (0 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSFontFaceSetCustom.cpp                                (rev 0)
+++ trunk/Source/WebCore/bindings/js/JSFontFaceSetCustom.cpp        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -0,0 +1,65 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;JSFontFaceSet.h&quot;
+
+#include &quot;FontFace.h&quot;
+#include &quot;JSFontFace.h&quot;
+#include &quot;JSKeyValueIterator.h&quot;
+
+namespace WebCore {
+
+using FontFaceSetIterator = JSKeyValueIterator&lt;JSFontFaceSet&gt;;
+using FontFaceSetIteratorPrototype = JSKeyValueIteratorPrototype&lt;JSFontFaceSet&gt;;
+
+template&lt;&gt;
+const JSC::ClassInfo FontFaceSetIterator::s_info = { &quot;Font Face Set Iterator&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(FontFaceSetIterator) };
+
+template&lt;&gt;
+const JSC::ClassInfo FontFaceSetIteratorPrototype::s_info = { &quot;Font Face Set Iterator Prototype&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(FontFaceSetIteratorPrototype) };
+
+JSC::JSValue JSFontFaceSet::ready(JSC::ExecState&amp; execState) const
+{
+    auto&amp; promise = wrapped().promise(execState);
+    return promise.deferred().promise();
+}
+
+JSC::JSValue JSFontFaceSet::entries(JSC::ExecState&amp;)
+{
+    return createIterator&lt;JSFontFaceSet&gt;(*globalObject(), *this, IterationKind::KeyValue);
+}
+
+JSC::JSValue JSFontFaceSet::keys(JSC::ExecState&amp;)
+{
+    return createIterator&lt;JSFontFaceSet&gt;(*globalObject(), *this, IterationKind::Key);
+}
+
+JSC::JSValue JSFontFaceSet::values(JSC::ExecState&amp;)
+{
+    return createIterator&lt;JSFontFaceSet&gt;(*globalObject(), *this, IterationKind::Value);
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/WebCore/bindings/js/JSFontFaceSetCustom.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceWebCorecssCSSAllInOnecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSAllInOne.cpp (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSAllInOne.cpp        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/Source/WebCore/css/CSSAllInOne.cpp        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -42,6 +42,7 @@
</span><span class="cx"> #include &quot;CSSFontFace.cpp&quot;
</span><span class="cx"> #include &quot;CSSFontFaceLoadEvent.cpp&quot;
</span><span class="cx"> #include &quot;CSSFontFaceRule.cpp&quot;
</span><ins>+#include &quot;CSSFontFaceSet.cpp&quot;
</ins><span class="cx"> #include &quot;CSSFontFaceSource.cpp&quot;
</span><span class="cx"> #include &quot;CSSFontFaceSrcValue.cpp&quot;
</span><span class="cx"> #include &quot;CSSFontFeatureValue.cpp&quot;
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSFontFacecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSFontFace.cpp (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSFontFace.cpp        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/Source/WebCore/css/CSSFontFace.cpp        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -45,9 +45,9 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-CSSFontFace::CSSFontFace(CSSFontFaceClient&amp; client, CSSFontSelector&amp; fontSelector, bool isLocalFallback)
</del><ins>+CSSFontFace::CSSFontFace(CSSFontSelector&amp; fontSelector, FontFace* wrapper, bool isLocalFallback)
</ins><span class="cx">     : m_fontSelector(fontSelector)
</span><del>-    , m_client(client)
</del><ins>+    , m_wrapper(wrapper)
</ins><span class="cx">     , m_isLocalFallback(isLocalFallback)
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -230,14 +230,14 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CSSFontFace::addedToSegmentedFontFace(CSSSegmentedFontFace&amp; segmentedFontFace)
</del><ins>+void CSSFontFace::addClient(Client&amp; client)
</ins><span class="cx"> {
</span><del>-    m_segmentedFontFaces.add(&amp;segmentedFontFace);
</del><ins>+    m_clients.add(&amp;client);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CSSFontFace::removedFromSegmentedFontFace(CSSSegmentedFontFace&amp; segmentedFontFace)
</del><ins>+void CSSFontFace::removeClient(Client&amp; client)
</ins><span class="cx"> {
</span><del>-    m_segmentedFontFaces.remove(&amp;segmentedFontFace);
</del><ins>+    m_clients.remove(&amp;client);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CSSFontFace::adoptSource(std::unique_ptr&lt;CSSFontFaceSource&gt;&amp;&amp; source)
</span><span class="lines">@@ -268,10 +268,10 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_status = newStatus;
</del><ins>+    for (auto&amp; client : m_clients)
+        client-&gt;stateChanged(*this, m_status, newStatus);
</ins><span class="cx"> 
</span><del>-    if (m_status == Status::Success || m_status == Status::Failure)
-        m_client.kick(*this);
</del><ins>+    m_status = newStatus;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CSSFontFace::fontLoaded(CSSFontFaceSource&amp;)
</span><span class="lines">@@ -282,13 +282,10 @@
</span><span class="cx">     if (m_sourcesPopulated)
</span><span class="cx">         pump();
</span><span class="cx"> 
</span><del>-    if (m_segmentedFontFaces.isEmpty())
-        return;
-
</del><span class="cx">     m_fontSelector-&gt;fontLoaded();
</span><span class="cx"> 
</span><del>-    for (auto* face : m_segmentedFontFaces)
-        face-&gt;fontLoaded(*this);
</del><ins>+    for (auto&amp; client : m_clients)
+        client-&gt;fontLoaded(*this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> size_t CSSFontFace::pump()
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSFontFaceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSFontFace.h (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSFontFace.h        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/Source/WebCore/css/CSSFontFace.h        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2007, 2008, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -44,16 +44,15 @@
</span><span class="cx"> class CSSValueList;
</span><span class="cx"> class FontDescription;
</span><span class="cx"> class Font;
</span><ins>+class FontFace;
</ins><span class="cx"> 
</span><del>-class CSSFontFaceClient {
</del><ins>+// FIXME: This class does not need to be reference counted.
+class CSSFontFace final : public RefCounted&lt;CSSFontFace&gt; {
</ins><span class="cx"> public:
</span><del>-    virtual ~CSSFontFaceClient() { }
-    virtual void kick(CSSFontFace&amp;) = 0;
-};
-
-class CSSFontFace : public RefCounted&lt;CSSFontFace&gt; {
-public:
-    static Ref&lt;CSSFontFace&gt; create(CSSFontFaceClient&amp; client, CSSFontSelector&amp; fontSelector, bool isLocalFallback = false) { return adoptRef(*new CSSFontFace(client, fontSelector, isLocalFallback)); }
</del><ins>+    static Ref&lt;CSSFontFace&gt; create(CSSFontSelector&amp; fontSelector, FontFace* wrapper = nullptr, bool isLocalFallback = false)
+    {
+        return adoptRef(*new CSSFontFace(fontSelector, wrapper, isLocalFallback));
+    }
</ins><span class="cx">     virtual ~CSSFontFace();
</span><span class="cx"> 
</span><span class="cx">     bool setFamilies(CSSValue&amp;);
</span><span class="lines">@@ -80,8 +79,9 @@
</span><span class="cx">     bool isLocalFallback() const { return m_isLocalFallback; }
</span><span class="cx">     Status status() const { return m_status; }
</span><span class="cx"> 
</span><del>-    void addedToSegmentedFontFace(CSSSegmentedFontFace&amp;);
-    void removedFromSegmentedFontFace(CSSSegmentedFontFace&amp;);
</del><ins>+    class Client;
+    void addClient(Client&amp;);
+    void removeClient(Client&amp;);
</ins><span class="cx"> 
</span><span class="cx">     bool allSourcesFailed() const;
</span><span class="cx"> 
</span><span class="lines">@@ -93,6 +93,13 @@
</span><span class="cx">     void load();
</span><span class="cx">     RefPtr&lt;Font&gt; font(const FontDescription&amp;, bool syntheticBold, bool syntheticItalic);
</span><span class="cx"> 
</span><ins>+    class Client {
+    public:
+        virtual ~Client() { }
+        virtual void fontLoaded(CSSFontFace&amp;) { };
+        virtual void stateChanged(CSSFontFace&amp;, Status oldState, Status newState) { UNUSED_PARAM(oldState); UNUSED_PARAM(newState); };
+    };
+
</ins><span class="cx">     // Pending =&gt; Loading  =&gt; TimedOut
</span><span class="cx">     //              ||  \\    //  ||
</span><span class="cx">     //              ||   \\  //   ||
</span><span class="lines">@@ -125,12 +132,14 @@
</span><span class="cx">         UChar32 m_to;
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    FontFace* wrapper() const { return m_wrapper; }
+
</ins><span class="cx"> #if ENABLE(SVG_FONTS)
</span><span class="cx">     bool hasSVGFontFaceSource() const;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    CSSFontFace(CSSFontFaceClient&amp;, CSSFontSelector&amp;, bool isLocalFallback);
</del><ins>+    CSSFontFace(CSSFontSelector&amp;, FontFace*, bool isLocalFallback);
</ins><span class="cx"> 
</span><span class="cx">     size_t pump();
</span><span class="cx">     void setStatus(Status);
</span><span class="lines">@@ -138,9 +147,9 @@
</span><span class="cx">     RefPtr&lt;CSSValueList&gt; m_families;
</span><span class="cx">     FontTraitsMask m_traitsMask { static_cast&lt;FontTraitsMask&gt;(FontStyleNormalMask | FontWeight400Mask) };
</span><span class="cx">     Vector&lt;UnicodeRange&gt; m_ranges;
</span><del>-    HashSet&lt;CSSSegmentedFontFace*&gt; m_segmentedFontFaces; // FIXME: Refactor this (in favor of CSSFontFaceClient) when implementing FontFaceSet.
</del><ins>+    HashSet&lt;Client*&gt; m_clients;
</ins><span class="cx">     Ref&lt;CSSFontSelector&gt; m_fontSelector;
</span><del>-    CSSFontFaceClient&amp; m_client;
</del><ins>+    FontFace* m_wrapper;
</ins><span class="cx">     FontFeatureSettings m_featureSettings;
</span><span class="cx">     FontVariantSettings m_variantSettings;
</span><span class="cx">     Vector&lt;std::unique_ptr&lt;CSSFontFaceSource&gt;&gt; m_sources;
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSFontFaceSetcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/css/CSSFontFaceSet.cpp (0 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSFontFaceSet.cpp                                (rev 0)
+++ trunk/Source/WebCore/css/CSSFontFaceSet.cpp        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -0,0 +1,196 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;CSSFontFaceSet.h&quot;
+
+#include &quot;CSSFontFamily.h&quot;
+#include &quot;CSSFontSelector.h&quot;
+#include &quot;CSSParser.h&quot;
+#include &quot;CSSPrimitiveValue.h&quot;
+#include &quot;CSSValueList.h&quot;
+#include &quot;StyleProperties.h&quot;
+
+namespace WebCore {
+
+CSSFontFaceSet::CSSFontFaceSet(CSSFontFaceSetClient&amp; client)
+    : m_client(client)
+{
+}
+
+CSSFontFaceSet::~CSSFontFaceSet()
+{
+    for (auto&amp; face : m_faces)
+        face-&gt;removeClient(*this);
+}
+
+void CSSFontFaceSet::incrementActiveCount()
+{
+    ++m_activeCount;
+    if (m_activeCount == 1) {
+        m_status = Status::Loading;
+        m_client.startedLoading();
+    }
+}
+
+void CSSFontFaceSet::decrementActiveCount()
+{
+    --m_activeCount;
+    if (!m_activeCount) {
+        m_status = Status::Loaded;
+        m_client.completedLoading();
+    }
+}
+
+bool CSSFontFaceSet::hasFace(const CSSFontFace&amp; face) const
+{
+    for (auto&amp; myFace : m_faces) {
+        if (myFace.ptr() == &amp;face)
+            return true;
+    }
+    return false;
+}
+
+void CSSFontFaceSet::add(CSSFontFace&amp; face)
+{
+    ASSERT(!hasFace(face));
+
+    m_faces.append(face);
+    face.addClient(*this);
+    if (face.status() == CSSFontFace::Status::Loading || face.status() == CSSFontFace::Status::TimedOut)
+        incrementActiveCount();
+}
+
+void CSSFontFaceSet::remove(const CSSFontFace&amp; face)
+{
+    for (size_t i = 0; i &lt; m_faces.size(); ++i) {
+        if (m_faces[i].ptr() == &amp;face) {
+            m_faces[i]-&gt;removeClient(*this);
+            m_faces.remove(i);
+            if (face.status() == CSSFontFace::Status::Loading || face.status() == CSSFontFace::Status::TimedOut)
+                decrementActiveCount();
+            return;
+        }
+    }
+    ASSERT_NOT_REACHED();
+}
+
+static HashSet&lt;String&gt; extractFamilies(const CSSValueList&amp; list)
+{
+    HashSet&lt;String&gt; result;
+    for (auto&amp; family : list) {
+        const CSSPrimitiveValue&amp; primitive = downcast&lt;CSSPrimitiveValue&gt;(family.get());
+        if (!primitive.isFontFamily())
+            continue;
+        result.add(primitive.fontFamily().familyName);
+    }
+    return result;
+}
+
+static bool familiesIntersect(const CSSFontFace&amp; face, const CSSValueList&amp; request)
+{
+    if (!face.families())
+        return false;
+
+    HashSet&lt;String&gt; faceFamilies = extractFamilies(*face.families());
+    HashSet&lt;String&gt; requestFamilies = extractFamilies(request);
+    for (auto&amp; family1 : faceFamilies) {
+        if (requestFamilies.contains(family1))
+            return true;
+    }
+    return false;
+}
+
+Vector&lt;std::reference_wrapper&lt;CSSFontFace&gt;&gt; CSSFontFaceSet::matchingFaces(const String&amp; font, const String&amp;, ExceptionCode&amp; ec)
+{
+    Vector&lt;std::reference_wrapper&lt;CSSFontFace&gt;&gt; result;
+    Ref&lt;MutableStyleProperties&gt; style = MutableStyleProperties::create();
+    auto parseResult = CSSParser::parseValue(style.ptr(), CSSPropertyFont, font, true, CSSStrictMode, nullptr);
+    if (parseResult == CSSParser::ParseResult::Error) {
+        ec = SYNTAX_ERR;
+        return result;
+    }
+    bool desiredStyleIsNormal = true;
+    if (RefPtr&lt;CSSValue&gt; desiredStyle = style-&gt;getPropertyCSSValue(CSSPropertyFontStyle)) {
+        if (!is&lt;CSSPrimitiveValue&gt;(*desiredStyle)) {
+            ec = SYNTAX_ERR;
+            return result;
+        }
+        desiredStyleIsNormal = downcast&lt;CSSPrimitiveValue&gt;(*desiredStyle).getValueID() == CSSValueNormal;
+    }
+    RefPtr&lt;CSSValue&gt; family = style-&gt;getPropertyCSSValue(CSSPropertyFontFamily);
+    if (!is&lt;CSSValueList&gt;(family.get())) {
+        ec = SYNTAX_ERR;
+        return result;
+    }
+    CSSValueList&amp; familyList = downcast&lt;CSSValueList&gt;(*family);
+
+    // Match CSSFontSelector::getFontFace()
+    for (auto&amp; face : m_faces) {
+        if (!familiesIntersect(face, familyList) || (desiredStyleIsNormal &amp;&amp; !(face-&gt;traitsMask() &amp; FontStyleNormalMask)))
+            continue;
+        result.append(face.get());
+    }
+    return result;
+}
+
+void CSSFontFaceSet::load(const String&amp; font, const String&amp; text, ExceptionCode&amp; ec)
+{
+    auto matchingFaces = this-&gt;matchingFaces(font, text, ec);
+    if (ec)
+        return;
+
+    for (auto&amp; face : matchingFaces)
+        face.get().load();
+}
+
+bool CSSFontFaceSet::check(const String&amp; font, const String&amp; text, ExceptionCode&amp; ec)
+{
+    auto matchingFaces = this-&gt;matchingFaces(font, text, ec);
+    if (ec)
+        return false;
+
+    for (auto&amp; face : matchingFaces) {
+        if (face.get().status() == CSSFontFace::Status::Pending)
+            return false;
+    }
+    return true;
+}
+
+void CSSFontFaceSet::stateChanged(CSSFontFace&amp; face, CSSFontFace::Status oldState, CSSFontFace::Status newState)
+{
+    ASSERT(hasFace(face));
+    if (oldState == CSSFontFace::Status::Pending) {
+        ASSERT(newState == CSSFontFace::Status::Loading);
+        incrementActiveCount();
+    }
+    if (newState == CSSFontFace::Status::Success || newState == CSSFontFace::Status::Failure) {
+        ASSERT(oldState == CSSFontFace::Status::Loading || oldState == CSSFontFace::Status::TimedOut);
+        m_client.faceFinished(face, newState);
+        decrementActiveCount();
+    }
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/WebCore/css/CSSFontFaceSet.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceWebCorecssCSSFontFaceSeth"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/css/CSSFontFaceSet.h (0 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSFontFaceSet.h                                (rev 0)
+++ trunk/Source/WebCore/css/CSSFontFaceSet.h        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -0,0 +1,80 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CSSFontFaceSet_h
+#define CSSFontFaceSet_h
+
+#include &quot;CSSFontFace.h&quot;
+#include &lt;wtf/Vector.h&gt;
+
+namespace WebCore {
+
+class FontFaceSet;
+
+class CSSFontFaceSetClient {
+public:
+    virtual ~CSSFontFaceSetClient() { }
+    virtual void faceFinished(CSSFontFace&amp;, CSSFontFace::Status) = 0;
+    virtual void startedLoading() = 0;
+    virtual void completedLoading() = 0;
+};
+
+class CSSFontFaceSet final : public CSSFontFace::Client {
+public:
+    CSSFontFaceSet(CSSFontFaceSetClient&amp;);
+    ~CSSFontFaceSet();
+
+    bool hasFace(const CSSFontFace&amp;) const;
+    size_t size() const { return m_faces.size(); }
+    void add(CSSFontFace&amp;);
+    void remove(const CSSFontFace&amp;);
+    const CSSFontFace&amp; operator[](size_t i) const { return m_faces[i]; }
+
+    void load(const String&amp; font, const String&amp; text, ExceptionCode&amp;);
+    bool check(const String&amp; font, const String&amp; text, ExceptionCode&amp;);
+
+    enum class Status {
+        Loading,
+        Loaded
+    };
+    Status status() const { return m_status; }
+
+    Vector&lt;std::reference_wrapper&lt;CSSFontFace&gt;&gt; matchingFaces(const String&amp; font, const String&amp; text, ExceptionCode&amp;);
+
+private:
+    void incrementActiveCount();
+    void decrementActiveCount();
+
+    virtual void stateChanged(CSSFontFace&amp;, CSSFontFace::Status oldState, CSSFontFace::Status newState) override;
+
+    Vector&lt;Ref&lt;CSSFontFace&gt;&gt; m_faces;
+    Status m_status { Status::Loaded };
+    CSSFontFaceSetClient&amp; m_client;
+    unsigned m_activeCount { 0 };
+};
+
+}
+
+#endif
</ins><span class="cx">Property changes on: trunk/Source/WebCore/css/CSSFontFaceSet.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceWebCorecssCSSFontSelectorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSFontSelector.cpp (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSFontSelector.cpp        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/Source/WebCore/css/CSSFontSelector.cpp        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -117,7 +117,7 @@
</span><span class="cx">     fontFace.sourcesPopulated();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static String familyNameFromPrimitive(const CSSPrimitiveValue&amp; value)
</del><ins>+String CSSFontSelector::familyNameFromPrimitive(const CSSPrimitiveValue&amp; value)
</ins><span class="cx"> {
</span><span class="cx">     if (value.isFontFamily())
</span><span class="cx">         return value.fontFamily().familyName;
</span><span class="lines">@@ -154,7 +154,7 @@
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;Ref&lt;CSSFontFace&gt;&gt; faces = { };
</span><span class="cx">     for (auto mask : traitsMasks) {
</span><del>-        Ref&lt;CSSFontFace&gt; face = CSSFontFace::create(*this, *this, true);
</del><ins>+        Ref&lt;CSSFontFace&gt; face = CSSFontFace::create(*this, nullptr, true);
</ins><span class="cx">         
</span><span class="cx">         RefPtr&lt;CSSValueList&gt; familyList = CSSValueList::createCommaSeparated();
</span><span class="cx">         familyList-&gt;append(CSSValuePool::singleton().createFontFamilyValue(familyName));
</span><span class="lines">@@ -201,7 +201,7 @@
</span><span class="cx">     if (!srcList.length())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    Ref&lt;CSSFontFace&gt; fontFace = CSSFontFace::create(*this, *this);
</del><ins>+    Ref&lt;CSSFontFace&gt; fontFace = CSSFontFace::create(*this);
</ins><span class="cx"> 
</span><span class="cx">     if (!fontFace-&gt;setFamilies(*fontFamily))
</span><span class="cx">         return;
</span><span class="lines">@@ -496,10 +496,6 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-void CSSFontSelector::kick(CSSFontFace&amp;)
-{
-}
-
</del><span class="cx"> size_t CSSFontSelector::fallbackFontCount()
</span><span class="cx"> {
</span><span class="cx">     if (!m_document)
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSFontSelectorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSFontSelector.h (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSFontSelector.h        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/Source/WebCore/css/CSSFontSelector.h        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -41,13 +41,14 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class CSSFontFaceRule;
</span><ins>+class CSSPrimitiveValue;
</ins><span class="cx"> class CSSSegmentedFontFace;
</span><span class="cx"> class CSSValueList;
</span><span class="cx"> class CachedFont;
</span><span class="cx"> class Document;
</span><span class="cx"> class StyleRuleFontFace;
</span><span class="cx"> 
</span><del>-class CSSFontSelector final : public FontSelector, public CSSFontFaceClient {
</del><ins>+class CSSFontSelector final : public FontSelector {
</ins><span class="cx"> public:
</span><span class="cx">     static Ref&lt;CSSFontSelector&gt; create(Document&amp; document)
</span><span class="cx">     {
</span><span class="lines">@@ -80,6 +81,8 @@
</span><span class="cx"> 
</span><span class="cx">     void beginLoadingFontSoon(CachedFont*);
</span><span class="cx"> 
</span><ins>+    static String familyNameFromPrimitive(const CSSPrimitiveValue&amp;);
+
</ins><span class="cx"> private:
</span><span class="cx">     explicit CSSFontSelector(Document&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -89,8 +92,6 @@
</span><span class="cx"> 
</span><span class="cx">     void registerLocalFontFacesForFamily(const String&amp;);
</span><span class="cx"> 
</span><del>-    void kick(CSSFontFace&amp;) override;
-
</del><span class="cx">     Document* m_document;
</span><span class="cx">     HashMap&lt;String, Vector&lt;Ref&lt;CSSFontFace&gt;&gt;, ASCIICaseInsensitiveHash&gt; m_fontFaces;
</span><span class="cx">     HashMap&lt;String, Vector&lt;Ref&lt;CSSFontFace&gt;&gt;, ASCIICaseInsensitiveHash&gt; m_locallyInstalledFontFaces;
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSSegmentedFontFacecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -45,19 +45,19 @@
</span><span class="cx"> CSSSegmentedFontFace::~CSSSegmentedFontFace()
</span><span class="cx"> {
</span><span class="cx">     for (auto&amp; face : m_fontFaces)
</span><del>-        face-&gt;removedFromSegmentedFontFace(*this);
</del><ins>+        face-&gt;removeClient(*this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CSSSegmentedFontFace::fontLoaded(CSSFontFace&amp;)
</del><ins>+void CSSSegmentedFontFace::appendFontFace(Ref&lt;CSSFontFace&gt;&amp;&amp; fontFace)
</ins><span class="cx"> {
</span><span class="cx">     m_cache.clear();
</span><ins>+    fontFace-&gt;addClient(*this);
+    m_fontFaces.append(WTFMove(fontFace));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CSSSegmentedFontFace::appendFontFace(Ref&lt;CSSFontFace&gt;&amp;&amp; fontFace)
</del><ins>+void CSSSegmentedFontFace::fontLoaded(CSSFontFace&amp;)
</ins><span class="cx"> {
</span><span class="cx">     m_cache.clear();
</span><del>-    fontFace-&gt;addedToSegmentedFontFace(*this);
-    m_fontFaces.append(WTFMove(fontFace));
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void appendFontWithInvalidUnicodeRangeIfLoading(FontRanges&amp; ranges, Ref&lt;Font&gt;&amp;&amp; font, const Vector&lt;CSSFontFace::UnicodeRange&gt;&amp; unicodeRanges)
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSSegmentedFontFaceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSSegmentedFontFace.h (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSSegmentedFontFace.h        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/Source/WebCore/css/CSSSegmentedFontFace.h        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #ifndef CSSSegmentedFontFace_h
</span><span class="cx"> #define CSSSegmentedFontFace_h
</span><span class="cx"> 
</span><ins>+#include &quot;CSSFontFace.h&quot;
</ins><span class="cx"> #include &quot;FontCache.h&quot;
</span><span class="cx"> #include &quot;FontRanges.h&quot;
</span><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="lines">@@ -35,11 +36,10 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-class CSSFontFace;
</del><span class="cx"> class CSSFontSelector;
</span><span class="cx"> class FontDescription;
</span><span class="cx"> 
</span><del>-class CSSSegmentedFontFace final {
</del><ins>+class CSSSegmentedFontFace final : public CSSFontFace::Client {
</ins><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><span class="cx">     CSSSegmentedFontFace(CSSFontSelector&amp;);
</span><span class="lines">@@ -47,13 +47,12 @@
</span><span class="cx"> 
</span><span class="cx">     CSSFontSelector&amp; fontSelector() const { return m_fontSelector; }
</span><span class="cx"> 
</span><del>-    void fontLoaded(CSSFontFace&amp;);
-
</del><span class="cx">     void appendFontFace(Ref&lt;CSSFontFace&gt;&amp;&amp;);
</span><span class="cx"> 
</span><span class="cx">     FontRanges fontRanges(const FontDescription&amp;);
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    virtual void fontLoaded(CSSFontFace&amp;) override;
</ins><span class="cx"> 
</span><span class="cx">     CSSFontSelector&amp; m_fontSelector;
</span><span class="cx">     HashMap&lt;FontDescriptionKey, FontRanges, FontDescriptionKeyHash, WTF::SimpleClassHashTraits&lt;FontDescriptionKey&gt;&gt; m_cache;
</span></span></pre></div>
<a id="trunkSourceWebCorecssFontFacecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/FontFace.cpp (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/FontFace.cpp        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/Source/WebCore/css/FontFace.cpp        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2007, 2008, 2011, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -111,13 +111,15 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> FontFace::FontFace(JSC::ExecState&amp; execState, CSSFontSelector&amp; fontSelector)
</span><del>-    : m_backing(CSSFontFace::create(*this, fontSelector))
</del><ins>+    : m_backing(CSSFontFace::create(fontSelector, this))
</ins><span class="cx">     , m_promise(createPromise(execState))
</span><span class="cx"> {
</span><ins>+    m_backing-&gt;addClient(*this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> FontFace::~FontFace()
</span><span class="cx"> {
</span><ins>+    m_backing-&gt;removeClient(*this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;CSSValue&gt; FontFace::parseString(const String&amp; string, CSSPropertyID propertyID)
</span><span class="lines">@@ -315,10 +317,10 @@
</span><span class="cx">     return String(&quot;error&quot;, String::ConstructFromLiteral);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void FontFace::kick(CSSFontFace&amp; face)
</del><ins>+void FontFace::stateChanged(CSSFontFace&amp; face, CSSFontFace::Status, CSSFontFace::Status newState)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT_UNUSED(face, &amp;face == m_backing.ptr());
</span><del>-    switch (m_backing-&gt;status()) {
</del><ins>+    switch (newState) {
</ins><span class="cx">     case CSSFontFace::Status::TimedOut:
</span><span class="cx">         rejectPromise(NETWORK_ERR);
</span><span class="cx">         return;
</span></span></pre></div>
<a id="trunkSourceWebCorecssFontFaceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/FontFace.h (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/FontFace.h        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/Source/WebCore/css/FontFace.h        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2007, 2008, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx"> class CSSValue;
</span><span class="cx"> class Dictionary;
</span><span class="cx"> 
</span><del>-class FontFace : public RefCounted&lt;FontFace&gt;, public CSSFontFaceClient {
</del><ins>+class FontFace final : public RefCounted&lt;FontFace&gt;, public CSSFontFace::Client {
</ins><span class="cx"> public:
</span><span class="cx">     static RefPtr&lt;FontFace&gt; create(JSC::ExecState&amp;, ScriptExecutionContext&amp;, const String&amp; family, const Deprecated::ScriptValue&amp; source, const Dictionary&amp; descriptors, ExceptionCode&amp;);
</span><span class="cx">     virtual ~FontFace();
</span><span class="lines">@@ -79,7 +79,7 @@
</span><span class="cx"> private:
</span><span class="cx">     FontFace(JSC::ExecState&amp;, CSSFontSelector&amp;);
</span><span class="cx"> 
</span><del>-    void kick(CSSFontFace&amp;) override;
</del><ins>+    virtual void stateChanged(CSSFontFace&amp;, CSSFontFace::Status oldState, CSSFontFace::Status newState) override;
</ins><span class="cx"> 
</span><span class="cx">     void fulfillPromise();
</span><span class="cx">     void rejectPromise(ExceptionCode);
</span></span></pre></div>
<a id="trunkSourceWebCorecssFontFaceSetcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/css/FontFaceSet.cpp (0 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/FontFaceSet.cpp                                (rev 0)
+++ trunk/Source/WebCore/css/FontFaceSet.cpp        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -0,0 +1,230 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;FontFaceSet.h&quot;
+
+#include &quot;Document.h&quot;
+#include &quot;ExceptionCodeDescription.h&quot;
+#include &quot;FontFace.h&quot;
+#include &quot;JSDOMBinding.h&quot;
+#include &quot;JSDOMCoreException.h&quot;
+#include &quot;JSFontFace.h&quot;
+#include &quot;JSFontFaceSet.h&quot;
+
+namespace WebCore {
+
+static FontFaceSet::Promise createPromise(JSC::ExecState&amp; exec)
+{
+    JSDOMGlobalObject&amp; globalObject = *JSC::jsCast&lt;JSDOMGlobalObject*&gt;(exec.lexicalGlobalObject());
+    return FontFaceSet::Promise(DeferredWrapper(&amp;exec, &amp;globalObject, JSC::JSPromiseDeferred::create(&amp;exec, &amp;globalObject)));
+}
+
+FontFaceSet::FontFaceSet(JSC::ExecState&amp; execState, Document&amp; document, const Vector&lt;RefPtr&lt;FontFace&gt;&gt;&amp; initialFaces)
+    : ActiveDOMObject(&amp;document)
+    , m_backing(*this)
+    , m_promise(createPromise(execState))
+{
+    for (auto&amp; face : initialFaces)
+        add(face.get());
+}
+
+FontFaceSet::~FontFaceSet()
+{
+}
+
+FontFaceSet::Iterator::Iterator(FontFaceSet&amp; set)
+    : m_target(set)
+{
+}
+
+bool FontFaceSet::Iterator::next(RefPtr&lt;FontFace&gt;&amp; key, RefPtr&lt;FontFace&gt;&amp; value)
+{
+    if (m_index == m_target-&gt;size())
+        return true;
+    key = m_target-&gt;m_backing[m_index++].wrapper();
+    value = key;
+    return false;
+}
+
+FontFaceSet::PendingPromise::PendingPromise(Promise&amp;&amp; promise)
+    : promise(WTFMove(promise))
+{
+}
+
+FontFaceSet::PendingPromise::~PendingPromise()
+{
+}
+
+bool FontFaceSet::has(FontFace* face) const
+{
+    if (!face)
+        return false;
+    return m_backing.hasFace(face-&gt;backing());
+}
+
+size_t FontFaceSet::size() const
+{
+    return m_backing.size();
+}
+
+FontFaceSet&amp; FontFaceSet::add(FontFace* face)
+{
+    if (face &amp;&amp; !m_backing.hasFace(face-&gt;backing()))
+        m_backing.add(face-&gt;backing());
+    return *this;
+}
+
+bool FontFaceSet::remove(FontFace* face)
+{
+    if (!face)
+        return false;
+
+    bool result = m_backing.hasFace(face-&gt;backing());
+    if (result)
+        m_backing.remove(face-&gt;backing());
+    return result;
+}
+
+void FontFaceSet::clear()
+{
+    while (m_backing.size())
+        m_backing.remove(m_backing[0]);
+}
+
+void FontFaceSet::load(const String&amp; font, const String&amp; text, DeferredWrapper&amp;&amp; promise, ExceptionCode&amp; ec)
+{
+    auto matchingFaces = m_backing.matchingFaces(font, text, ec);
+    if (ec)
+        return;
+
+    if (matchingFaces.isEmpty()) {
+        promise.resolve(Vector&lt;RefPtr&lt;FontFace&gt;&gt;());
+        return;
+    }
+
+    for (auto&amp; face : matchingFaces)
+        face.get().load();
+
+    auto pendingPromise = PendingPromise::create(WTFMove(promise));
+    bool waiting = false;
+
+    for (auto&amp; face : matchingFaces) {
+        if (face.get().status() == CSSFontFace::Status::Failure) {
+            pendingPromise-&gt;promise.reject(DOMCoreException::create(ExceptionCodeDescription(NETWORK_ERR)));
+            return;
+        }
+    }
+
+    for (auto&amp; face : matchingFaces) {
+        pendingPromise-&gt;faces.append(face.get().wrapper());
+        if (face.get().status() == CSSFontFace::Status::Success)
+            continue;
+        waiting = true;
+        auto&amp; vector = m_pendingPromises.add(RefPtr&lt;FontFace&gt;(face.get().wrapper()), Vector&lt;Ref&lt;PendingPromise&gt;&gt;()).iterator-&gt;value;
+        vector.append(pendingPromise.copyRef());
+    }
+
+    if (!waiting)
+        pendingPromise-&gt;promise.resolve(pendingPromise-&gt;faces);
+}
+
+bool FontFaceSet::check(const String&amp; family, const String&amp; text, ExceptionCode&amp; ec)
+{
+    return m_backing.check(family, text, ec);
+}
+
+auto FontFaceSet::promise(JSC::ExecState&amp; execState) -&gt; Promise&amp;
+{
+    if (!m_promise) {
+        m_promise = createPromise(execState);
+        if (m_backing.status() == CSSFontFaceSet::Status::Loaded)
+            fulfillPromise();
+    }
+    return m_promise.value();
+}
+    
+String FontFaceSet::status() const
+{
+    switch (m_backing.status()) {
+    case CSSFontFaceSet::Status::Loading:
+        return String(&quot;loading&quot;, String::ConstructFromLiteral);
+    case CSSFontFaceSet::Status::Loaded:
+        return String(&quot;loaded&quot;, String::ConstructFromLiteral);
+    }
+    ASSERT_NOT_REACHED();
+    return String(&quot;loaded&quot;, String::ConstructFromLiteral);
+}
+
+bool FontFaceSet::canSuspendForDocumentSuspension() const
+{
+    return m_backing.status() == CSSFontFaceSet::Status::Loaded;
+}
+
+void FontFaceSet::startedLoading()
+{
+    // FIXME: Fire a &quot;loading&quot; event asynchronously.
+}
+
+void FontFaceSet::completedLoading()
+{
+    if (m_promise)
+        fulfillPromise();
+    m_promise = Nullopt;
+    // FIXME: Fire a &quot;loadingdone&quot; and possibly a &quot;loadingerror&quot; event asynchronously.
+}
+
+void FontFaceSet::fulfillPromise()
+{
+    // Normally, DeferredWrapper::callFunction resets the reference to the promise.
+    // However, API semantics require our promise to live for the entire lifetime of the FontFace.
+    // Let's make sure it stays alive.
+
+    Promise guard(m_promise.value());
+    m_promise.value().resolve(*this);
+    m_promise = guard;
+}
+
+void FontFaceSet::faceFinished(CSSFontFace&amp; face, CSSFontFace::Status newStatus)
+{
+    auto iterator = m_pendingPromises.find(face.wrapper());
+    if (iterator == m_pendingPromises.end())
+        return;
+
+    for (auto&amp; pendingPromise : iterator-&gt;value) {
+        if (newStatus == CSSFontFace::Status::Success) {
+            if (pendingPromise-&gt;hasOneRef())
+                pendingPromise-&gt;promise.resolve(pendingPromise-&gt;faces);
+        } else {
+            ASSERT(newStatus == CSSFontFace::Status::Failure);
+            // The first resolution wins, so we can just reject early now.
+            pendingPromise-&gt;promise.reject(DOMCoreException::create(ExceptionCodeDescription(NETWORK_ERR)));
+        }
+    }
+
+    m_pendingPromises.remove(iterator);
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/WebCore/css/FontFaceSet.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceWebCorecssFontFaceSeth"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/css/FontFaceSet.h (0 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/FontFaceSet.h                                (rev 0)
+++ trunk/Source/WebCore/css/FontFaceSet.h        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -0,0 +1,133 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FontFaceSet_h
+#define FontFaceSet_h
+
+#include &quot;ActiveDOMObject.h&quot;
+#include &quot;CSSFontFaceSet.h&quot;
+#include &quot;DOMCoreException.h&quot;
+#include &quot;EventTarget.h&quot;
+#include &quot;JSDOMPromise.h&quot;
+#include &lt;wtf/Optional.h&gt;
+#include &lt;wtf/Ref.h&gt;
+#include &lt;wtf/RefCounted.h&gt;
+#include &lt;wtf/RefPtr.h&gt;
+#include &lt;wtf/Vector.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
+namespace WebCore {
+
+class Document;
+class FontFace;
+
+class FontFaceSet final : public RefCounted&lt;FontFaceSet&gt;, public CSSFontFaceSetClient, public EventTargetWithInlineData, public ActiveDOMObject {
+public:
+    static Ref&lt;FontFaceSet&gt; create(JSC::ExecState&amp; execState, Document&amp; document, const Vector&lt;RefPtr&lt;FontFace&gt;&gt;&amp; initialFaces)
+    {
+        Ref&lt;FontFaceSet&gt; result = adoptRef(*new FontFaceSet(execState, document, initialFaces));
+        result-&gt;suspendIfNeeded();
+        return result;
+    }
+    virtual ~FontFaceSet();
+
+    bool has(FontFace*) const;
+    size_t size() const;
+    FontFaceSet&amp; add(FontFace*);
+    bool remove(FontFace*);
+    void clear();
+
+    void load(const String&amp; font, DeferredWrapper&amp;&amp; promise, ExceptionCode&amp; ec) { load(font, String(&quot; &quot;, String::ConstructFromLiteral), WTFMove(promise), ec); }
+    void load(const String&amp; font, const String&amp; text, DeferredWrapper&amp;&amp; promise, ExceptionCode&amp;);
+    bool check(const String&amp; font, ExceptionCode&amp; ec) { return check(font, String(&quot; &quot;, String::ConstructFromLiteral), ec); }
+    bool check(const String&amp; font, const String&amp; text, ExceptionCode&amp;);
+    
+    String status() const;
+
+    typedef DOMPromise&lt;FontFaceSet&amp;, DOMCoreException&amp;&gt; Promise;
+    Promise&amp; promise(JSC::ExecState&amp;);
+
+    class Iterator {
+    public:
+        explicit Iterator(FontFaceSet&amp;);
+
+        using Key = RefPtr&lt;FontFace&gt;;
+        using Value = RefPtr&lt;FontFace&gt;;
+
+        bool next(Key&amp; nextKey, Value&amp; nextValue);
+
+    private:
+        Ref&lt;FontFaceSet&gt; m_target;
+        size_t m_index { 0 };
+    };
+    Iterator createIterator() { return Iterator(*this); }
+
+    using RefCounted&lt;FontFaceSet&gt;::ref;
+    using RefCounted&lt;FontFaceSet&gt;::deref;
+
+private:
+    struct PendingPromise : public RefCounted&lt;PendingPromise&gt; {
+        typedef DOMPromise&lt;Vector&lt;RefPtr&lt;FontFace&gt;&gt;&amp;, DOMCoreException&amp;&gt; Promise;
+        static Ref&lt;PendingPromise&gt; create(Promise&amp;&amp; promise)
+        {
+            return adoptRef(*new PendingPromise(WTFMove(promise)));
+        }
+        ~PendingPromise();
+
+    private:
+        PendingPromise(Promise&amp;&amp;);
+
+    public:
+        Vector&lt;RefPtr&lt;FontFace&gt;&gt; faces;
+        Promise promise;
+    };
+
+    FontFaceSet(JSC::ExecState&amp;, Document&amp;, const Vector&lt;RefPtr&lt;FontFace&gt;&gt;&amp;);
+
+    void fulfillPromise();
+
+    // CSSFontFaceSetClient
+    virtual void startedLoading() override;
+    virtual void completedLoading() override;
+    virtual void faceFinished(CSSFontFace&amp;, CSSFontFace::Status) override;
+
+    // ActiveDOMObject
+    virtual const char* activeDOMObjectName() const override { return &quot;FontFaceSet&quot;; }
+    virtual bool canSuspendForDocumentSuspension() const override;
+
+    // EventTarget
+    virtual EventTargetInterface eventTargetInterface() const override { return FontFaceSetEventTargetInterfaceType; }
+    virtual ScriptExecutionContext* scriptExecutionContext() const override { return ActiveDOMObject::scriptExecutionContext(); }
+    virtual void refEventTarget() override { ref(); }
+    virtual void derefEventTarget() override { deref(); }
+
+    CSSFontFaceSet m_backing;
+    HashMap&lt;RefPtr&lt;FontFace&gt;, Vector&lt;Ref&lt;PendingPromise&gt;&gt;&gt; m_pendingPromises;
+    Optional&lt;Promise&gt; m_promise;
+};
+
+}
+
+#endif
</ins><span class="cx">Property changes on: trunk/Source/WebCore/css/FontFaceSet.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceWebCorecssFontFaceSetidl"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/css/FontFaceSet.idl (0 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/FontFaceSet.idl                                (rev 0)
+++ trunk/Source/WebCore/css/FontFaceSet.idl        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -0,0 +1,56 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+enum FontFaceSetLoadStatus {
+    &quot;loading&quot;,
+    &quot;loaded&quot;
+};
+
+[
+    ConstructorCallWith=ScriptState&amp;Document,
+    Constructor(sequence&lt;FontFace&gt; initialFaces)
+] interface FontFaceSet : EventTarget {
+    [Custom] Object entries();
+    // forEach(): Maybe implement this in Javascript on top of keys().
+    boolean has(FontFace font);
+    [Custom] Object keys();
+    [Custom] Object values();
+    // @iterator
+    readonly attribute long size;
+
+    FontFaceSet add(FontFace font);
+    [ImplementedAs=remove] boolean delete(FontFace font);
+    void clear();
+
+    attribute EventHandler onloading;
+    attribute EventHandler onloadingdone;
+    attribute EventHandler onloadingerror;
+
+    [RaisesException] Promise load(DOMString font, optional DOMString text);
+    [RaisesException] boolean check(DOMString font, optional DOMString text);
+
+    [Custom] readonly attribute Promise ready;
+    readonly attribute FontFaceSetLoadStatus status;
+};
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkSourceWebCoredomEventNamesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/EventNames.h (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/EventNames.h        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/Source/WebCore/dom/EventNames.h        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -141,6 +141,7 @@
</span><span class="cx">     macro(loadend) \
</span><span class="cx">     macro(loading) \
</span><span class="cx">     macro(loadingdone) \
</span><ins>+    macro(loadingerror) \
</ins><span class="cx">     macro(loadstart) \
</span><span class="cx">     macro(mark) \
</span><span class="cx">     macro(message) \
</span></span></pre></div>
<a id="trunkSourceWebCoredomEventTargetFactoryin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/EventTargetFactory.in (196746 => 196747)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/EventTargetFactory.in        2016-02-18 06:37:45 UTC (rev 196746)
+++ trunk/Source/WebCore/dom/EventTargetFactory.in        2016-02-18 07:25:56 UTC (rev 196747)
</span><span class="lines">@@ -9,7 +9,7 @@
</span><span class="cx"> DOMWindow
</span><span class="cx"> EventSource
</span><span class="cx"> FileReader
</span><del>-FontLoader conditional=FONT_LOAD_EVENTS
</del><ins>+FontFaceSet
</ins><span class="cx"> IDBDatabase conditional=INDEXED_DATABASE
</span><span class="cx"> IDBOpenDBRequest conditional=INDEXED_DATABASE
</span><span class="cx"> IDBRequest conditional=INDEXED_DATABASE
</span></span></pre>
</div>
</div>

</body>
</html>