OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are met: | 5 * modification, are permitted provided that the following conditions are met: |
6 * | 6 * |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 } | 107 } |
108 } | 108 } |
109 | 109 |
110 DEFINE_TRACE(LoadFontPromiseResolver) | 110 DEFINE_TRACE(LoadFontPromiseResolver) |
111 { | 111 { |
112 visitor->trace(m_fontFaces); | 112 visitor->trace(m_fontFaces); |
113 visitor->trace(m_resolver); | 113 visitor->trace(m_resolver); |
114 LoadFontCallback::trace(visitor); | 114 LoadFontCallback::trace(visitor); |
115 } | 115 } |
116 | 116 |
117 class FontsReadyPromiseResolver final : public GarbageCollected<FontsReadyPromis eResolver> { | |
118 public: | |
119 static FontsReadyPromiseResolver* create(ScriptState* scriptState) | |
120 { | |
121 return new FontsReadyPromiseResolver(scriptState); | |
122 } | |
123 | |
124 void resolve(PassRefPtrWillBeRawPtr<FontFaceSet> fontFaceSet) | |
125 { | |
126 m_resolver->resolve(fontFaceSet); | |
127 } | |
128 | |
129 ScriptPromise promise() { return m_resolver->promise(); } | |
130 | |
131 DEFINE_INLINE_TRACE() | |
132 { | |
133 visitor->trace(m_resolver); | |
134 } | |
135 | |
136 private: | |
137 explicit FontsReadyPromiseResolver(ScriptState* scriptState) | |
138 : m_resolver(ScriptPromiseResolver::create(scriptState)) | |
139 { | |
140 } | |
141 | |
142 Member<ScriptPromiseResolver> m_resolver; | |
143 }; | |
144 | |
145 FontFaceSet::FontFaceSet(Document& document) | 117 FontFaceSet::FontFaceSet(Document& document) |
146 : ActiveDOMObject(&document) | 118 : ActiveDOMObject(&document) |
147 , m_shouldFireLoadingEvent(false) | 119 , m_shouldFireLoadingEvent(false) |
148 , m_isLoading(false) | 120 , m_isLoading(false) |
149 , m_asyncRunner(this, &FontFaceSet::handlePendingEventsAndPromises) | 121 , m_asyncRunner(this, &FontFaceSet::handlePendingEventsAndPromises) |
150 { | 122 { |
151 suspendIfNeeded(); | 123 suspendIfNeeded(); |
152 } | 124 } |
153 | 125 |
154 FontFaceSet::~FontFaceSet() | 126 FontFaceSet::~FontFaceSet() |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
192 void FontFaceSet::handlePendingEventsAndPromisesSoon() | 164 void FontFaceSet::handlePendingEventsAndPromisesSoon() |
193 { | 165 { |
194 // m_asyncRunner will be automatically stopped on destruction. | 166 // m_asyncRunner will be automatically stopped on destruction. |
195 m_asyncRunner.runAsync(); | 167 m_asyncRunner.runAsync(); |
196 } | 168 } |
197 | 169 |
198 void FontFaceSet::didLayout() | 170 void FontFaceSet::didLayout() |
199 { | 171 { |
200 if (document()->frame()->isMainFrame() && m_loadingFonts.isEmpty()) | 172 if (document()->frame()->isMainFrame() && m_loadingFonts.isEmpty()) |
201 m_histogram.record(); | 173 m_histogram.record(); |
202 if (!m_loadingFonts.isEmpty() || (!m_isLoading && m_readyResolvers.isEmpty() )) | 174 if (!shouldSignalReady()) |
203 return; | 175 return; |
204 handlePendingEventsAndPromisesSoon(); | 176 handlePendingEventsAndPromisesSoon(); |
205 } | 177 } |
206 | 178 |
179 bool FontFaceSet::shouldSignalReady() const | |
180 { | |
181 if (!m_loadingFonts.isEmpty()) | |
182 return false; | |
183 return m_isLoading || (m_ready && m_ready->state() == ReadyProperty::Pending ); | |
184 } | |
185 | |
207 void FontFaceSet::handlePendingEventsAndPromises() | 186 void FontFaceSet::handlePendingEventsAndPromises() |
208 { | 187 { |
209 fireLoadingEvent(); | 188 fireLoadingEvent(); |
210 fireDoneEventIfPossible(); | 189 fireDoneEventIfPossible(); |
211 } | 190 } |
212 | 191 |
213 void FontFaceSet::fireLoadingEvent() | 192 void FontFaceSet::fireLoadingEvent() |
214 { | 193 { |
215 if (m_shouldFireLoadingEvent) { | 194 if (m_shouldFireLoadingEvent) { |
216 m_shouldFireLoadingEvent = false; | 195 m_shouldFireLoadingEvent = false; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
251 m_histogram.updateStatus(fontFace); | 230 m_histogram.updateStatus(fontFace); |
252 m_failedFonts.append(fontFace); | 231 m_failedFonts.append(fontFace); |
253 removeFromLoadingFonts(fontFace); | 232 removeFromLoadingFonts(fontFace); |
254 } | 233 } |
255 | 234 |
256 void FontFaceSet::addToLoadingFonts(PassRefPtrWillBeRawPtr<FontFace> fontFace) | 235 void FontFaceSet::addToLoadingFonts(PassRefPtrWillBeRawPtr<FontFace> fontFace) |
257 { | 236 { |
258 if (!m_isLoading) { | 237 if (!m_isLoading) { |
259 m_isLoading = true; | 238 m_isLoading = true; |
260 m_shouldFireLoadingEvent = true; | 239 m_shouldFireLoadingEvent = true; |
240 if (m_ready && m_ready->state() != ReadyProperty::Pending) | |
241 m_ready->reset(); | |
261 handlePendingEventsAndPromisesSoon(); | 242 handlePendingEventsAndPromisesSoon(); |
262 } | 243 } |
263 m_loadingFonts.add(fontFace); | 244 m_loadingFonts.add(fontFace); |
264 } | 245 } |
265 | 246 |
266 void FontFaceSet::removeFromLoadingFonts(PassRefPtrWillBeRawPtr<FontFace> fontFa ce) | 247 void FontFaceSet::removeFromLoadingFonts(PassRefPtrWillBeRawPtr<FontFace> fontFa ce) |
267 { | 248 { |
268 m_loadingFonts.remove(fontFace); | 249 m_loadingFonts.remove(fontFace); |
269 if (m_loadingFonts.isEmpty()) | 250 if (m_loadingFonts.isEmpty()) |
270 handlePendingEventsAndPromisesSoon(); | 251 handlePendingEventsAndPromisesSoon(); |
271 } | 252 } |
272 | 253 |
273 ScriptPromise FontFaceSet::ready(ScriptState* scriptState) | 254 ScriptPromise FontFaceSet::ready(ScriptState* scriptState) |
274 { | 255 { |
275 if (!inActiveDocumentContext()) | 256 if (!inActiveDocumentContext()) |
276 return ScriptPromise(); | 257 return ScriptPromise(); |
277 FontsReadyPromiseResolver* resolver = FontsReadyPromiseResolver::create(scri ptState); | 258 |
278 ScriptPromise promise = resolver->promise(); | 259 if (!m_ready) |
dominicc (has gone to gerrit)
2015/09/02 00:14:06
Pretty much everyone creates these lazily, and whi
Kunihiko Sakamoto
2015/09/02 05:05:42
Done.
I think m_isLoading is still needed, since F
| |
279 m_readyResolvers.append(resolver); | 260 m_ready = new ReadyProperty(executionContext(), this, ReadyProperty::Rea dy); |
280 handlePendingEventsAndPromisesSoon(); | 261 handlePendingEventsAndPromisesSoon(); |
281 return promise; | 262 return m_ready->promise(scriptState->world()); |
282 } | 263 } |
283 | 264 |
284 void FontFaceSet::add(FontFace* fontFace, ExceptionState& exceptionState) | 265 void FontFaceSet::add(FontFace* fontFace, ExceptionState& exceptionState) |
285 { | 266 { |
286 if (!inActiveDocumentContext()) | 267 if (!inActiveDocumentContext()) |
287 return; | 268 return; |
288 if (!fontFace) { | 269 if (!fontFace) { |
289 exceptionState.throwTypeError("The argument is not a FontFace."); | 270 exceptionState.throwTypeError("The argument is not a FontFace."); |
290 return; | 271 return; |
291 } | 272 } |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
399 { | 380 { |
400 if (!inActiveDocumentContext()) | 381 if (!inActiveDocumentContext()) |
401 return m_nonCSSConnectedFaces.size(); | 382 return m_nonCSSConnectedFaces.size(); |
402 return cssConnectedFontFaceList().size() + m_nonCSSConnectedFaces.size(); | 383 return cssConnectedFontFaceList().size() + m_nonCSSConnectedFaces.size(); |
403 } | 384 } |
404 | 385 |
405 void FontFaceSet::fireDoneEventIfPossible() | 386 void FontFaceSet::fireDoneEventIfPossible() |
406 { | 387 { |
407 if (m_shouldFireLoadingEvent) | 388 if (m_shouldFireLoadingEvent) |
408 return; | 389 return; |
409 if (!m_loadingFonts.isEmpty() || (!m_isLoading && m_readyResolvers.isEmpty() )) | 390 if (!shouldSignalReady()) |
410 return; | 391 return; |
411 | 392 |
412 // If the layout was invalidated in between when we thought layout | 393 // If the layout was invalidated in between when we thought layout |
413 // was updated and when we're ready to fire the event, just wait | 394 // was updated and when we're ready to fire the event, just wait |
414 // until after the next layout before firing events. | 395 // until after the next layout before firing events. |
415 Document* d = document(); | 396 Document* d = document(); |
416 if (!d->view() || d->view()->needsLayout()) | 397 if (!d->view() || d->view()->needsLayout()) |
417 return; | 398 return; |
418 | 399 |
419 if (m_isLoading) { | 400 if (m_isLoading) { |
420 RefPtrWillBeRawPtr<FontFaceSetLoadEvent> doneEvent = nullptr; | 401 RefPtrWillBeRawPtr<FontFaceSetLoadEvent> doneEvent = nullptr; |
421 RefPtrWillBeRawPtr<FontFaceSetLoadEvent> errorEvent = nullptr; | 402 RefPtrWillBeRawPtr<FontFaceSetLoadEvent> errorEvent = nullptr; |
422 doneEvent = FontFaceSetLoadEvent::createForFontFaces(EventTypeNames::loa dingdone, m_loadedFonts); | 403 doneEvent = FontFaceSetLoadEvent::createForFontFaces(EventTypeNames::loa dingdone, m_loadedFonts); |
423 m_loadedFonts.clear(); | 404 m_loadedFonts.clear(); |
424 if (!m_failedFonts.isEmpty()) { | 405 if (!m_failedFonts.isEmpty()) { |
425 errorEvent = FontFaceSetLoadEvent::createForFontFaces(EventTypeNames ::loadingerror, m_failedFonts); | 406 errorEvent = FontFaceSetLoadEvent::createForFontFaces(EventTypeNames ::loadingerror, m_failedFonts); |
426 m_failedFonts.clear(); | 407 m_failedFonts.clear(); |
427 } | 408 } |
428 m_isLoading = false; | 409 m_isLoading = false; |
429 dispatchEvent(doneEvent); | 410 dispatchEvent(doneEvent); |
430 if (errorEvent) | 411 if (errorEvent) |
431 dispatchEvent(errorEvent); | 412 dispatchEvent(errorEvent); |
432 } | 413 } |
433 | 414 |
434 if (!m_readyResolvers.isEmpty()) { | 415 if (m_ready && m_ready->state() == ReadyProperty::Pending) |
435 HeapVector<Member<FontsReadyPromiseResolver>> resolvers; | 416 m_ready->resolve(this); |
436 m_readyResolvers.swap(resolvers); | |
437 for (size_t index = 0; index < resolvers.size(); ++index) | |
438 resolvers[index]->resolve(this); | |
439 } | |
440 } | 417 } |
441 | 418 |
442 ScriptPromise FontFaceSet::load(ScriptState* scriptState, const String& fontStri ng, const String& text) | 419 ScriptPromise FontFaceSet::load(ScriptState* scriptState, const String& fontStri ng, const String& text) |
443 { | 420 { |
444 if (!inActiveDocumentContext()) | 421 if (!inActiveDocumentContext()) |
445 return ScriptPromise(); | 422 return ScriptPromise(); |
446 | 423 |
447 Font font; | 424 Font font; |
448 if (!resolveFontStyle(fontString, font)) { | 425 if (!resolveFontStyle(fontString, font)) { |
449 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptSt ate); | 426 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptSt ate); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
575 | 552 |
576 void FontFaceSet::didLayout(Document& document) | 553 void FontFaceSet::didLayout(Document& document) |
577 { | 554 { |
578 if (FontFaceSet* fonts = static_cast<FontFaceSet*>(SupplementType::from(docu ment, supplementName()))) | 555 if (FontFaceSet* fonts = static_cast<FontFaceSet*>(SupplementType::from(docu ment, supplementName()))) |
579 fonts->didLayout(); | 556 fonts->didLayout(); |
580 } | 557 } |
581 | 558 |
582 DEFINE_TRACE(FontFaceSet) | 559 DEFINE_TRACE(FontFaceSet) |
583 { | 560 { |
584 #if ENABLE(OILPAN) | 561 #if ENABLE(OILPAN) |
562 visitor->trace(m_ready); | |
585 visitor->trace(m_loadingFonts); | 563 visitor->trace(m_loadingFonts); |
586 visitor->trace(m_readyResolvers); | |
587 visitor->trace(m_loadedFonts); | 564 visitor->trace(m_loadedFonts); |
588 visitor->trace(m_failedFonts); | 565 visitor->trace(m_failedFonts); |
589 visitor->trace(m_nonCSSConnectedFaces); | 566 visitor->trace(m_nonCSSConnectedFaces); |
590 HeapSupplement<Document>::trace(visitor); | 567 HeapSupplement<Document>::trace(visitor); |
591 #endif | 568 #endif |
592 EventTargetWithInlineData::trace(visitor); | 569 EventTargetWithInlineData::trace(visitor); |
593 ActiveDOMObject::trace(visitor); | 570 ActiveDOMObject::trace(visitor); |
594 } | 571 } |
595 | 572 |
596 } // namespace blink | 573 } // namespace blink |
OLD | NEW |