| 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) |
| 121 , m_ready(new ReadyProperty(executionContext(), this, ReadyProperty::Ready)) |
| 149 , m_asyncRunner(this, &FontFaceSet::handlePendingEventsAndPromises) | 122 , m_asyncRunner(this, &FontFaceSet::handlePendingEventsAndPromises) |
| 150 { | 123 { |
| 151 suspendIfNeeded(); | 124 suspendIfNeeded(); |
| 152 } | 125 } |
| 153 | 126 |
| 154 FontFaceSet::~FontFaceSet() | 127 FontFaceSet::~FontFaceSet() |
| 155 { | 128 { |
| 156 } | 129 } |
| 157 | 130 |
| 158 Document* FontFaceSet::document() const | 131 Document* FontFaceSet::document() const |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 void FontFaceSet::handlePendingEventsAndPromisesSoon() | 165 void FontFaceSet::handlePendingEventsAndPromisesSoon() |
| 193 { | 166 { |
| 194 // m_asyncRunner will be automatically stopped on destruction. | 167 // m_asyncRunner will be automatically stopped on destruction. |
| 195 m_asyncRunner.runAsync(); | 168 m_asyncRunner.runAsync(); |
| 196 } | 169 } |
| 197 | 170 |
| 198 void FontFaceSet::didLayout() | 171 void FontFaceSet::didLayout() |
| 199 { | 172 { |
| 200 if (document()->frame()->isMainFrame() && m_loadingFonts.isEmpty()) | 173 if (document()->frame()->isMainFrame() && m_loadingFonts.isEmpty()) |
| 201 m_histogram.record(); | 174 m_histogram.record(); |
| 202 if (!m_loadingFonts.isEmpty() || (!m_isLoading && m_readyResolvers.isEmpty()
)) | 175 if (!shouldSignalReady()) |
| 203 return; | 176 return; |
| 204 handlePendingEventsAndPromisesSoon(); | 177 handlePendingEventsAndPromisesSoon(); |
| 205 } | 178 } |
| 206 | 179 |
| 180 bool FontFaceSet::shouldSignalReady() const |
| 181 { |
| 182 if (!m_loadingFonts.isEmpty()) |
| 183 return false; |
| 184 return m_isLoading || m_ready->state() == ReadyProperty::Pending; |
| 185 } |
| 186 |
| 207 void FontFaceSet::handlePendingEventsAndPromises() | 187 void FontFaceSet::handlePendingEventsAndPromises() |
| 208 { | 188 { |
| 209 fireLoadingEvent(); | 189 fireLoadingEvent(); |
| 210 fireDoneEventIfPossible(); | 190 fireDoneEventIfPossible(); |
| 211 } | 191 } |
| 212 | 192 |
| 213 void FontFaceSet::fireLoadingEvent() | 193 void FontFaceSet::fireLoadingEvent() |
| 214 { | 194 { |
| 215 if (m_shouldFireLoadingEvent) { | 195 if (m_shouldFireLoadingEvent) { |
| 216 m_shouldFireLoadingEvent = false; | 196 m_shouldFireLoadingEvent = false; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 m_histogram.updateStatus(fontFace); | 231 m_histogram.updateStatus(fontFace); |
| 252 m_failedFonts.append(fontFace); | 232 m_failedFonts.append(fontFace); |
| 253 removeFromLoadingFonts(fontFace); | 233 removeFromLoadingFonts(fontFace); |
| 254 } | 234 } |
| 255 | 235 |
| 256 void FontFaceSet::addToLoadingFonts(PassRefPtrWillBeRawPtr<FontFace> fontFace) | 236 void FontFaceSet::addToLoadingFonts(PassRefPtrWillBeRawPtr<FontFace> fontFace) |
| 257 { | 237 { |
| 258 if (!m_isLoading) { | 238 if (!m_isLoading) { |
| 259 m_isLoading = true; | 239 m_isLoading = true; |
| 260 m_shouldFireLoadingEvent = true; | 240 m_shouldFireLoadingEvent = true; |
| 241 if (m_ready->state() != ReadyProperty::Pending) |
| 242 m_ready->reset(); |
| 261 handlePendingEventsAndPromisesSoon(); | 243 handlePendingEventsAndPromisesSoon(); |
| 262 } | 244 } |
| 263 m_loadingFonts.add(fontFace); | 245 m_loadingFonts.add(fontFace); |
| 264 } | 246 } |
| 265 | 247 |
| 266 void FontFaceSet::removeFromLoadingFonts(PassRefPtrWillBeRawPtr<FontFace> fontFa
ce) | 248 void FontFaceSet::removeFromLoadingFonts(PassRefPtrWillBeRawPtr<FontFace> fontFa
ce) |
| 267 { | 249 { |
| 268 m_loadingFonts.remove(fontFace); | 250 m_loadingFonts.remove(fontFace); |
| 269 if (m_loadingFonts.isEmpty()) | 251 if (m_loadingFonts.isEmpty()) |
| 270 handlePendingEventsAndPromisesSoon(); | 252 handlePendingEventsAndPromisesSoon(); |
| 271 } | 253 } |
| 272 | 254 |
| 273 ScriptPromise FontFaceSet::ready(ScriptState* scriptState) | 255 ScriptPromise FontFaceSet::ready(ScriptState* scriptState) |
| 274 { | 256 { |
| 275 if (!inActiveDocumentContext()) | 257 return m_ready->promise(scriptState->world()); |
| 276 return ScriptPromise(); | |
| 277 FontsReadyPromiseResolver* resolver = FontsReadyPromiseResolver::create(scri
ptState); | |
| 278 ScriptPromise promise = resolver->promise(); | |
| 279 m_readyResolvers.append(resolver); | |
| 280 handlePendingEventsAndPromisesSoon(); | |
| 281 return promise; | |
| 282 } | 258 } |
| 283 | 259 |
| 284 void FontFaceSet::add(FontFace* fontFace, ExceptionState& exceptionState) | 260 void FontFaceSet::add(FontFace* fontFace, ExceptionState& exceptionState) |
| 285 { | 261 { |
| 286 if (!inActiveDocumentContext()) | 262 if (!inActiveDocumentContext()) |
| 287 return; | 263 return; |
| 288 if (!fontFace) { | 264 if (!fontFace) { |
| 289 exceptionState.throwTypeError("The argument is not a FontFace."); | 265 exceptionState.throwTypeError("The argument is not a FontFace."); |
| 290 return; | 266 return; |
| 291 } | 267 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 { | 375 { |
| 400 if (!inActiveDocumentContext()) | 376 if (!inActiveDocumentContext()) |
| 401 return m_nonCSSConnectedFaces.size(); | 377 return m_nonCSSConnectedFaces.size(); |
| 402 return cssConnectedFontFaceList().size() + m_nonCSSConnectedFaces.size(); | 378 return cssConnectedFontFaceList().size() + m_nonCSSConnectedFaces.size(); |
| 403 } | 379 } |
| 404 | 380 |
| 405 void FontFaceSet::fireDoneEventIfPossible() | 381 void FontFaceSet::fireDoneEventIfPossible() |
| 406 { | 382 { |
| 407 if (m_shouldFireLoadingEvent) | 383 if (m_shouldFireLoadingEvent) |
| 408 return; | 384 return; |
| 409 if (!m_loadingFonts.isEmpty() || (!m_isLoading && m_readyResolvers.isEmpty()
)) | 385 if (!shouldSignalReady()) |
| 410 return; | 386 return; |
| 411 | 387 |
| 412 // If the layout was invalidated in between when we thought layout | 388 // 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 | 389 // was updated and when we're ready to fire the event, just wait |
| 414 // until after the next layout before firing events. | 390 // until after the next layout before firing events. |
| 415 Document* d = document(); | 391 Document* d = document(); |
| 416 if (!d->view() || d->view()->needsLayout()) | 392 if (!d->view() || d->view()->needsLayout()) |
| 417 return; | 393 return; |
| 418 | 394 |
| 419 if (m_isLoading) { | 395 if (m_isLoading) { |
| 420 RefPtrWillBeRawPtr<FontFaceSetLoadEvent> doneEvent = nullptr; | 396 RefPtrWillBeRawPtr<FontFaceSetLoadEvent> doneEvent = nullptr; |
| 421 RefPtrWillBeRawPtr<FontFaceSetLoadEvent> errorEvent = nullptr; | 397 RefPtrWillBeRawPtr<FontFaceSetLoadEvent> errorEvent = nullptr; |
| 422 doneEvent = FontFaceSetLoadEvent::createForFontFaces(EventTypeNames::loa
dingdone, m_loadedFonts); | 398 doneEvent = FontFaceSetLoadEvent::createForFontFaces(EventTypeNames::loa
dingdone, m_loadedFonts); |
| 423 m_loadedFonts.clear(); | 399 m_loadedFonts.clear(); |
| 424 if (!m_failedFonts.isEmpty()) { | 400 if (!m_failedFonts.isEmpty()) { |
| 425 errorEvent = FontFaceSetLoadEvent::createForFontFaces(EventTypeNames
::loadingerror, m_failedFonts); | 401 errorEvent = FontFaceSetLoadEvent::createForFontFaces(EventTypeNames
::loadingerror, m_failedFonts); |
| 426 m_failedFonts.clear(); | 402 m_failedFonts.clear(); |
| 427 } | 403 } |
| 428 m_isLoading = false; | 404 m_isLoading = false; |
| 429 dispatchEvent(doneEvent); | 405 dispatchEvent(doneEvent); |
| 430 if (errorEvent) | 406 if (errorEvent) |
| 431 dispatchEvent(errorEvent); | 407 dispatchEvent(errorEvent); |
| 432 } | 408 } |
| 433 | 409 |
| 434 if (!m_readyResolvers.isEmpty()) { | 410 if (m_ready->state() == ReadyProperty::Pending) |
| 435 HeapVector<Member<FontsReadyPromiseResolver>> resolvers; | 411 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 } | 412 } |
| 441 | 413 |
| 442 ScriptPromise FontFaceSet::load(ScriptState* scriptState, const String& fontStri
ng, const String& text) | 414 ScriptPromise FontFaceSet::load(ScriptState* scriptState, const String& fontStri
ng, const String& text) |
| 443 { | 415 { |
| 444 if (!inActiveDocumentContext()) | 416 if (!inActiveDocumentContext()) |
| 445 return ScriptPromise(); | 417 return ScriptPromise(); |
| 446 | 418 |
| 447 Font font; | 419 Font font; |
| 448 if (!resolveFontStyle(fontString, font)) { | 420 if (!resolveFontStyle(fontString, font)) { |
| 449 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptSt
ate); | 421 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptSt
ate); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 | 547 |
| 576 void FontFaceSet::didLayout(Document& document) | 548 void FontFaceSet::didLayout(Document& document) |
| 577 { | 549 { |
| 578 if (FontFaceSet* fonts = static_cast<FontFaceSet*>(SupplementType::from(docu
ment, supplementName()))) | 550 if (FontFaceSet* fonts = static_cast<FontFaceSet*>(SupplementType::from(docu
ment, supplementName()))) |
| 579 fonts->didLayout(); | 551 fonts->didLayout(); |
| 580 } | 552 } |
| 581 | 553 |
| 582 DEFINE_TRACE(FontFaceSet) | 554 DEFINE_TRACE(FontFaceSet) |
| 583 { | 555 { |
| 584 #if ENABLE(OILPAN) | 556 #if ENABLE(OILPAN) |
| 557 visitor->trace(m_ready); |
| 585 visitor->trace(m_loadingFonts); | 558 visitor->trace(m_loadingFonts); |
| 586 visitor->trace(m_readyResolvers); | |
| 587 visitor->trace(m_loadedFonts); | 559 visitor->trace(m_loadedFonts); |
| 588 visitor->trace(m_failedFonts); | 560 visitor->trace(m_failedFonts); |
| 589 visitor->trace(m_nonCSSConnectedFaces); | 561 visitor->trace(m_nonCSSConnectedFaces); |
| 590 HeapSupplement<Document>::trace(visitor); | 562 HeapSupplement<Document>::trace(visitor); |
| 591 #endif | 563 #endif |
| 592 EventTargetWithInlineData::trace(visitor); | 564 EventTargetWithInlineData::trace(visitor); |
| 593 ActiveDOMObject::trace(visitor); | 565 ActiveDOMObject::trace(visitor); |
| 594 } | 566 } |
| 595 | 567 |
| 596 } // namespace blink | 568 } // namespace blink |
| OLD | NEW |