OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2006 Eric Seidel <eric@webkit.org> | 2 * Copyright (C) 2006 Eric Seidel <eric@webkit.org> |
3 * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. | 3 * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. |
4 * Copyright (C) Research In Motion Limited 2011. All rights reserved. | 4 * Copyright (C) Research In Motion Limited 2011. All rights reserved. |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
60 #include "platform/graphics/paint/PaintRecord.h" | 60 #include "platform/graphics/paint/PaintRecord.h" |
61 #include "platform/graphics/paint/PaintRecordBuilder.h" | 61 #include "platform/graphics/paint/PaintRecordBuilder.h" |
62 #include "platform/instrumentation/tracing/TraceEvent.h" | 62 #include "platform/instrumentation/tracing/TraceEvent.h" |
63 #include "wtf/PassRefPtr.h" | 63 #include "wtf/PassRefPtr.h" |
64 | 64 |
65 namespace blink { | 65 namespace blink { |
66 | 66 |
67 SVGImage::SVGImage(ImageObserver* observer) | 67 SVGImage::SVGImage(ImageObserver* observer) |
68 : Image(observer), | 68 : Image(observer), |
69 m_paintController(PaintController::create()), | 69 m_paintController(PaintController::create()), |
70 m_hasPendingTimelineRewind(false) {} | 70 m_hasPendingTimelineRewind(false), |
71 m_weakPtrFactory(this) {} | |
71 | 72 |
72 SVGImage::~SVGImage() { | 73 SVGImage::~SVGImage() { |
73 if (m_page) { | 74 if (m_page) { |
74 // Store m_page in a local variable, clearing m_page, so that | 75 // Store m_page in a local variable, clearing m_page, so that |
75 // SVGImageChromeClient knows we're destructed. | 76 // SVGImageChromeClient knows we're destructed. |
76 Page* currentPage = m_page.release(); | 77 Page* currentPage = m_page.release(); |
77 // Break both the loader and view references to the frame | 78 // Break both the loader and view references to the frame |
78 currentPage->willBeDestroyed(); | 79 currentPage->willBeDestroyed(); |
79 } | 80 } |
80 | 81 |
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
553 } | 554 } |
554 | 555 |
555 void SVGImage::updateUseCounters(const Document& document) const { | 556 void SVGImage::updateUseCounters(const Document& document) const { |
556 if (SVGSVGElement* rootElement = svgRootElement(m_page.get())) { | 557 if (SVGSVGElement* rootElement = svgRootElement(m_page.get())) { |
557 if (rootElement->timeContainer()->hasAnimations()) | 558 if (rootElement->timeContainer()->hasAnimations()) |
558 UseCounter::count(document, | 559 UseCounter::count(document, |
559 UseCounter::SVGSMILAnimationInImageRegardlessOfCache); | 560 UseCounter::SVGSMILAnimationInImageRegardlessOfCache); |
560 } | 561 } |
561 } | 562 } |
562 | 563 |
564 // SVGImageLocalFrameClient is used to wait until SVG document's load event | |
565 // in the case where there are subresources asynchronously loaded. | |
566 class SVGImage::SVGImageLocalFrameClient : public EmptyLocalFrameClient { | |
567 public: | |
568 SVGImageLocalFrameClient(WeakPtr<SVGImage> image) : m_image(image) {} | |
569 | |
570 private: | |
571 void dispatchDidHandleOnloadEvents() override { | |
572 // The SVGImage is destructed before SVG load completion. | |
573 if (!m_image) | |
574 return; | |
575 | |
576 switch (m_image->m_loadStatus) { | |
fs
2017/03/15 14:22:17
Could we have this just call a method on SVGImage,
hiroshige
2017/05/04 22:50:50
Done.
| |
577 case InDataChanged: | |
578 m_image->m_loadStatus = LoadCompletedWithinDataChanged; | |
579 break; | |
580 | |
581 case AfterDataChanged: | |
582 m_image->m_loadStatus = LoadCompletedAsynchronously; | |
583 if (m_image->getImageObserver()) | |
584 m_image->getImageObserver()->loadCompleted(m_image.get()); | |
585 break; | |
586 | |
587 case DataChangedNotStarted: | |
588 case LoadCompletedWithinDataChanged: | |
589 case LoadCompletedAsynchronously: | |
590 CHECK(false); | |
591 break; | |
592 } | |
593 } | |
594 WeakPtr<SVGImage> m_image; | |
595 }; | |
596 | |
563 Image::SizeAvailability SVGImage::dataChanged(bool allDataReceived) { | 597 Image::SizeAvailability SVGImage::dataChanged(bool allDataReceived) { |
564 TRACE_EVENT0("blink", "SVGImage::dataChanged"); | 598 TRACE_EVENT0("blink", "SVGImage::dataChanged"); |
565 | 599 |
566 // Don't do anything if is an empty image. | 600 // Don't do anything if is an empty image. |
567 if (!data()->size()) | 601 if (!data()->size()) |
568 return SizeAvailable; | 602 return SizeAvailable; |
569 | 603 |
570 if (allDataReceived) { | 604 if (!allDataReceived) |
605 return m_page ? SizeAvailable : SizeUnavailable; | |
606 | |
607 CHECK(!m_page); | |
608 | |
609 { | |
kouhei (in TOK)
2017/03/15 11:32:34
remove { and unindent
hiroshige
2017/05/04 22:50:50
Done.
| |
571 // SVGImage will fire events (and the default C++ handlers run) but doesn't | 610 // SVGImage will fire events (and the default C++ handlers run) but doesn't |
572 // actually allow script to run so it's fine to call into it. We allow this | 611 // actually allow script to run so it's fine to call into it. We allow this |
573 // since it means an SVG data url can synchronously load like other image | 612 // since it means an SVG data url can synchronously load like other image |
574 // types. | 613 // types. |
575 EventDispatchForbiddenScope::AllowUserAgentEvents allowUserAgentEvents; | 614 EventDispatchForbiddenScope::AllowUserAgentEvents allowUserAgentEvents; |
576 | 615 |
577 DEFINE_STATIC_LOCAL(LocalFrameClient, dummyLocalFrameClient, | 616 CHECK_EQ(m_loadStatus, DataChangedNotStarted); |
578 (EmptyLocalFrameClient::create())); | 617 m_loadStatus = InDataChanged; |
579 | |
580 CHECK(!m_page); | |
581 | 618 |
582 Page::PageClients pageClients; | 619 Page::PageClients pageClients; |
583 fillWithEmptyClients(pageClients); | 620 fillWithEmptyClients(pageClients); |
584 m_chromeClient = SVGImageChromeClient::create(this); | 621 m_chromeClient = SVGImageChromeClient::create(this); |
585 pageClients.chromeClient = m_chromeClient.get(); | 622 pageClients.chromeClient = m_chromeClient.get(); |
586 | 623 |
587 // FIXME: If this SVG ends up loading itself, we might leak the world. | 624 // FIXME: If this SVG ends up loading itself, we might leak the world. |
588 // The Cache code does not know about ImageResources holding Frames and | 625 // The Cache code does not know about ImageResources holding Frames and |
589 // won't know to break the cycle. | 626 // won't know to break the cycle. |
590 // This will become an issue when SVGImage will be able to load other | 627 // This will become an issue when SVGImage will be able to load other |
(...skipping 22 matching lines...) Expand all Loading... | |
613 page->settings().setDefaultFontSize( | 650 page->settings().setDefaultFontSize( |
614 defaultSettings.getDefaultFontSize()); | 651 defaultSettings.getDefaultFontSize()); |
615 page->settings().setDefaultFixedFontSize( | 652 page->settings().setDefaultFixedFontSize( |
616 defaultSettings.getDefaultFixedFontSize()); | 653 defaultSettings.getDefaultFixedFontSize()); |
617 } | 654 } |
618 } | 655 } |
619 | 656 |
620 LocalFrame* frame = nullptr; | 657 LocalFrame* frame = nullptr; |
621 { | 658 { |
622 TRACE_EVENT0("blink", "SVGImage::dataChanged::createFrame"); | 659 TRACE_EVENT0("blink", "SVGImage::dataChanged::createFrame"); |
623 frame = LocalFrame::create(&dummyLocalFrameClient, &page->frameHost(), 0); | 660 frame = |
661 LocalFrame::create(new SVGImageLocalFrameClient(this->asWeakPtr()), | |
fs
2017/03/15 14:22:17
What is the case that prompts the use of a WeakPtr
hiroshige
2017/05/04 22:50:50
While I don't know concrete cases, the following i
fs
2017/05/05 10:52:42
Yes, a RefPtr would certainly not work. With the c
hiroshige
2017/05/08 17:22:06
Oh, and I noticed we cannot use WeakPtr with Threa
hiroshige
2017/05/08 18:37:11
So, this means SVGImage is always alive when the n
fs
2017/05/08 18:52:33
Yes, AFAICS.
| |
662 &page->frameHost(), 0); | |
624 frame->setView(FrameView::create(*frame)); | 663 frame->setView(FrameView::create(*frame)); |
625 frame->init(); | 664 frame->init(); |
626 } | 665 } |
627 | 666 |
628 FrameLoader& loader = frame->loader(); | 667 FrameLoader& loader = frame->loader(); |
629 loader.forceSandboxFlags(SandboxAll); | 668 loader.forceSandboxFlags(SandboxAll); |
630 | 669 |
631 frame->view()->setScrollbarsSuppressed(true); | 670 frame->view()->setScrollbarsSuppressed(true); |
632 // SVG Images will always synthesize a viewBox, if it's not available, and | 671 // SVG Images will always synthesize a viewBox, if it's not available, and |
633 // thus never see scrollbars. | 672 // thus never see scrollbars. |
634 frame->view()->setCanHaveScrollbars(false); | 673 frame->view()->setCanHaveScrollbars(false); |
635 // SVG Images are transparent. | 674 // SVG Images are transparent. |
636 frame->view()->setTransparent(true); | 675 frame->view()->setTransparent(true); |
637 | 676 |
638 m_page = page; | 677 m_page = page; |
639 | 678 |
640 TRACE_EVENT0("blink", "SVGImage::dataChanged::load"); | 679 TRACE_EVENT0("blink", "SVGImage::dataChanged::load"); |
641 loader.load(FrameLoadRequest( | 680 loader.load(FrameLoadRequest( |
642 0, blankURL(), | 681 0, blankURL(), |
643 SubstituteData(data(), AtomicString("image/svg+xml"), | 682 SubstituteData(data(), AtomicString("image/svg+xml"), |
644 AtomicString("UTF-8"), KURL(), ForceSynchronousLoad))); | 683 AtomicString("UTF-8"), KURL(), ForceSynchronousLoad))); |
645 | 684 |
646 // Set the concrete object size before a container size is available. | 685 // Set the concrete object size before a container size is available. |
647 m_intrinsicSize = roundedIntSize(concreteObjectSize(FloatSize( | 686 m_intrinsicSize = roundedIntSize(concreteObjectSize(FloatSize( |
648 LayoutReplaced::defaultWidth, LayoutReplaced::defaultHeight))); | 687 LayoutReplaced::defaultWidth, LayoutReplaced::defaultHeight))); |
649 } | 688 } |
650 | 689 |
651 return m_page ? SizeAvailable : SizeUnavailable; | 690 DCHECK(m_page); |
691 switch (m_loadStatus) { | |
692 case InDataChanged: | |
693 m_loadStatus = AfterDataChanged; | |
694 return SizeAvailableAndLoadingAsynchronously; | |
695 | |
696 case LoadCompletedWithinDataChanged: | |
697 return SizeAvailable; | |
698 | |
699 case DataChangedNotStarted: | |
700 case AfterDataChanged: | |
701 case LoadCompletedAsynchronously: | |
702 CHECK(false); | |
703 break; | |
704 } | |
705 | |
706 NOTREACHED(); | |
707 return SizeAvailable; | |
652 } | 708 } |
653 | 709 |
654 String SVGImage::filenameExtension() const { | 710 String SVGImage::filenameExtension() const { |
655 return "svg"; | 711 return "svg"; |
656 } | 712 } |
657 | 713 |
658 } // namespace blink | 714 } // namespace blink |
OLD | NEW |