Chromium Code Reviews| 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 |