Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp

Issue 2613853002: Phase III Step 2: Call imageNotifyFinished() and image load event after SVG loading completes (Closed)
Patch Set: Rebase Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698