2 * Copyright (C) 2016 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include "ActiveDOMObject.h"
30 #include "CSSFontFaceSet.h"
31 #include "DOMCoreException.h"
32 #include "EventTarget.h"
33 #include "JSDOMPromise.h"
34 #include <wtf/HashTraits.h>
35 #include <wtf/Optional.h>
37 #include <wtf/RefCounted.h>
38 #include <wtf/RefPtr.h>
39 #include <wtf/Vector.h>
40 #include <wtf/text/WTFString.h>
51 class FontFaceSet final : public RefCounted<FontFaceSet>, public CSSFontFaceSetClient, public EventTargetWithInlineData, public ActiveDOMObject {
53 static Ref<FontFaceSet> create(Document&, const Vector<RefPtr<FontFace>>& initialFaces);
54 static Ref<FontFaceSet> create(Document&, CSSFontFaceSet& backing);
55 virtual ~FontFaceSet();
57 bool has(RefPtr<WebCore::FontFace>) const;
59 FontFaceSet& add(RefPtr<WebCore::FontFace>);
60 bool remove(RefPtr<WebCore::FontFace>);
63 void load(JSC::ExecState& execState, const String& font, DeferredWrapper&& promise, ExceptionCode& ec) { load(execState, font, String(" ", String::ConstructFromLiteral), WTFMove(promise), ec); }
64 void load(JSC::ExecState&, const String& font, const String& text, DeferredWrapper&& promise, ExceptionCode&);
65 bool check(const String& font, ExceptionCode& ec) { return check(font, String(" ", String::ConstructFromLiteral), ec); }
66 bool check(const String& font, const String& text, ExceptionCode&);
68 String status() const;
70 typedef DOMPromise<FontFaceSet&, DOMCoreException&> Promise;
71 Promise& promise(JSC::ExecState&);
73 CSSFontFaceSet& backing() { return m_backing; }
77 explicit Iterator(FontFaceSet&);
78 Optional<WTF::KeyValuePair<RefPtr<FontFace>, RefPtr<FontFace>>> next(JSC::ExecState&);
81 Ref<FontFaceSet> m_target;
82 size_t m_index { 0 }; // FIXME: There needs to be a mechanism to handle when fonts are added or removed from the middle of the FontFaceSet.
84 Iterator createIterator() { return Iterator(*this); }
86 using RefCounted<FontFaceSet>::ref;
87 using RefCounted<FontFaceSet>::deref;
90 struct PendingPromise : public RefCounted<PendingPromise> {
91 typedef DOMPromise<Vector<RefPtr<FontFace>>&, DOMCoreException&> Promise;
92 static Ref<PendingPromise> create(Promise&& promise)
94 return adoptRef(*new PendingPromise(WTFMove(promise)));
99 PendingPromise(Promise&&);
102 Vector<RefPtr<FontFace>> faces;
104 bool hasReachedTerminalState { false };
107 FontFaceSet(Document&, const Vector<RefPtr<FontFace>>&);
108 FontFaceSet(Document&, CSSFontFaceSet&);
110 void fulfillPromise();
112 // CSSFontFaceSetClient
113 void startedLoading() override;
114 void completedLoading() override;
115 void faceFinished(CSSFontFace&, CSSFontFace::Status) override;
118 const char* activeDOMObjectName() const override { return "FontFaceSet"; }
119 bool canSuspendForDocumentSuspension() const override;
122 EventTargetInterface eventTargetInterface() const override { return FontFaceSetEventTargetInterfaceType; }
123 ScriptExecutionContext* scriptExecutionContext() const override { return ActiveDOMObject::scriptExecutionContext(); }
124 void refEventTarget() override { ref(); }
125 void derefEventTarget() override { deref(); }
127 Ref<CSSFontFaceSet> m_backing;
128 HashMap<RefPtr<CSSFontFace>, Vector<Ref<PendingPromise>>> m_pendingPromises;
129 Optional<Promise> m_promise;