| 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 #include "platform/graphics/paint/PaintRecord.h" | 61 #include "platform/graphics/paint/PaintRecord.h" |
| 62 #include "platform/graphics/paint/PaintRecordBuilder.h" | 62 #include "platform/graphics/paint/PaintRecordBuilder.h" |
| 63 #include "platform/instrumentation/tracing/TraceEvent.h" | 63 #include "platform/instrumentation/tracing/TraceEvent.h" |
| 64 #include "platform/wtf/PassRefPtr.h" | 64 #include "platform/wtf/PassRefPtr.h" |
| 65 | 65 |
| 66 namespace blink { | 66 namespace blink { |
| 67 | 67 |
| 68 SVGImage::SVGImage(ImageObserver* observer) | 68 SVGImage::SVGImage(ImageObserver* observer) |
| 69 : Image(observer), | 69 : Image(observer), |
| 70 paint_controller_(PaintController::Create()), | 70 paint_controller_(PaintController::Create()), |
| 71 has_pending_timeline_rewind_(false) {} | 71 has_pending_timeline_rewind_(false), |
| 72 weak_ptr_factory_(this) {} |
| 72 | 73 |
| 73 SVGImage::~SVGImage() { | 74 SVGImage::~SVGImage() { |
| 74 if (page_) { | 75 if (page_) { |
| 75 // Store m_page in a local variable, clearing m_page, so that | 76 // Store m_page in a local variable, clearing m_page, so that |
| 76 // SVGImageChromeClient knows we're destructed. | 77 // SVGImageChromeClient knows we're destructed. |
| 77 Page* current_page = page_.Release(); | 78 Page* current_page = page_.Release(); |
| 78 // Break both the loader and view references to the frame | 79 // Break both the loader and view references to the frame |
| 79 current_page->WillBeDestroyed(); | 80 current_page->WillBeDestroyed(); |
| 80 } | 81 } |
| 81 | 82 |
| (...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 } | 599 } |
| 599 | 600 |
| 600 void SVGImage::UpdateUseCounters(const Document& document) const { | 601 void SVGImage::UpdateUseCounters(const Document& document) const { |
| 601 if (SVGSVGElement* root_element = SvgRootElement(page_.Get())) { | 602 if (SVGSVGElement* root_element = SvgRootElement(page_.Get())) { |
| 602 if (root_element->TimeContainer()->HasAnimations()) | 603 if (root_element->TimeContainer()->HasAnimations()) |
| 603 UseCounter::Count(document, | 604 UseCounter::Count(document, |
| 604 UseCounter::kSVGSMILAnimationInImageRegardlessOfCache); | 605 UseCounter::kSVGSMILAnimationInImageRegardlessOfCache); |
| 605 } | 606 } |
| 606 } | 607 } |
| 607 | 608 |
| 609 // SVGImageLocalFrameClient is used to wait until SVG document's load event |
| 610 // in the case where there are subresources asynchronously loaded. |
| 611 class SVGImage::SVGImageLocalFrameClient : public EmptyLocalFrameClient { |
| 612 public: |
| 613 SVGImageLocalFrameClient(WeakPtr<SVGImage> image) : image_(image) {} |
| 614 |
| 615 private: |
| 616 void DispatchDidHandleOnloadEvents() override { |
| 617 // The SVGImage was destructed before SVG load completion. |
| 618 if (!image_) |
| 619 return; |
| 620 |
| 621 image_->LoadCompleted(); |
| 622 } |
| 623 WeakPtr<SVGImage> image_; |
| 624 }; |
| 625 |
| 626 void SVGImage::LoadCompleted() { |
| 627 switch (load_state_) { |
| 628 case kInDataChanged: |
| 629 load_state_ = kLoadCompleted; |
| 630 break; |
| 631 |
| 632 case kWaitingForAsyncLoadCompletion: |
| 633 load_state_ = kLoadCompleted; |
| 634 if (GetImageObserver()) |
| 635 GetImageObserver()->AsyncLoadCompleted(this); |
| 636 break; |
| 637 |
| 638 case kDataChangedNotStarted: |
| 639 case kLoadCompleted: |
| 640 CHECK(false); |
| 641 break; |
| 642 } |
| 643 } |
| 644 |
| 608 Image::SizeAvailability SVGImage::DataChanged(bool all_data_received) { | 645 Image::SizeAvailability SVGImage::DataChanged(bool all_data_received) { |
| 609 TRACE_EVENT0("blink", "SVGImage::dataChanged"); | 646 TRACE_EVENT0("blink", "SVGImage::dataChanged"); |
| 610 | 647 |
| 611 // Don't do anything if is an empty image. | 648 // Don't do anything if is an empty image. |
| 612 if (!Data()->size()) | 649 if (!Data()->size()) |
| 613 return kSizeAvailable; | 650 return kSizeAvailable; |
| 614 | 651 |
| 615 if (all_data_received) { | 652 if (!all_data_received) |
| 616 // SVGImage will fire events (and the default C++ handlers run) but doesn't | 653 return page_ ? kSizeAvailable : kSizeUnavailable; |
| 617 // actually allow script to run so it's fine to call into it. We allow this | |
| 618 // since it means an SVG data url can synchronously load like other image | |
| 619 // types. | |
| 620 EventDispatchForbiddenScope::AllowUserAgentEvents allow_user_agent_events; | |
| 621 | 654 |
| 622 DEFINE_STATIC_LOCAL(LocalFrameClient, dummy_local_frame_client, | 655 CHECK(!page_); |
| 623 (EmptyLocalFrameClient::Create())); | |
| 624 | 656 |
| 625 CHECK(!page_); | 657 // SVGImage will fire events (and the default C++ handlers run) but doesn't |
| 658 // actually allow script to run so it's fine to call into it. We allow this |
| 659 // since it means an SVG data url can synchronously load like other image |
| 660 // types. |
| 661 EventDispatchForbiddenScope::AllowUserAgentEvents allow_user_agent_events; |
| 626 | 662 |
| 627 Page::PageClients page_clients; | 663 CHECK_EQ(load_state_, kDataChangedNotStarted); |
| 628 FillWithEmptyClients(page_clients); | 664 load_state_ = kInDataChanged; |
| 629 chrome_client_ = SVGImageChromeClient::Create(this); | |
| 630 page_clients.chrome_client = chrome_client_.Get(); | |
| 631 | 665 |
| 632 // FIXME: If this SVG ends up loading itself, we might leak the world. | 666 Page::PageClients page_clients; |
| 633 // The Cache code does not know about ImageResources holding Frames and | 667 FillWithEmptyClients(page_clients); |
| 634 // won't know to break the cycle. | 668 chrome_client_ = SVGImageChromeClient::Create(this); |
| 635 // This will become an issue when SVGImage will be able to load other | 669 page_clients.chrome_client = chrome_client_.Get(); |
| 636 // SVGImage objects, but we're safe now, because SVGImage can only be | |
| 637 // loaded by a top-level document. | |
| 638 Page* page; | |
| 639 { | |
| 640 TRACE_EVENT0("blink", "SVGImage::dataChanged::createPage"); | |
| 641 page = Page::Create(page_clients); | |
| 642 page->GetSettings().SetScriptEnabled(false); | |
| 643 page->GetSettings().SetPluginsEnabled(false); | |
| 644 page->GetSettings().SetAcceleratedCompositingEnabled(false); | |
| 645 | 670 |
| 646 // Because this page is detached, it can't get default font settings | 671 // FIXME: If this SVG ends up loading itself, we might leak the world. |
| 647 // from the embedder. Copy over font settings so we have sensible | 672 // The Cache code does not know about ImageResources holding Frames and |
| 648 // defaults. These settings are fixed and will not update if changed. | 673 // won't know to break the cycle. |
| 649 if (!Page::OrdinaryPages().IsEmpty()) { | 674 // This will become an issue when SVGImage will be able to load other |
| 650 Settings& default_settings = | 675 // SVGImage objects, but we're safe now, because SVGImage can only be |
| 651 (*Page::OrdinaryPages().begin())->GetSettings(); | 676 // loaded by a top-level document. |
| 652 page->GetSettings().GetGenericFontFamilySettings() = | 677 Page* page; |
| 653 default_settings.GetGenericFontFamilySettings(); | 678 { |
| 654 page->GetSettings().SetMinimumFontSize( | 679 TRACE_EVENT0("blink", "SVGImage::dataChanged::createPage"); |
| 655 default_settings.GetMinimumFontSize()); | 680 page = Page::Create(page_clients); |
| 656 page->GetSettings().SetMinimumLogicalFontSize( | 681 page->GetSettings().SetScriptEnabled(false); |
| 657 default_settings.GetMinimumLogicalFontSize()); | 682 page->GetSettings().SetPluginsEnabled(false); |
| 658 page->GetSettings().SetDefaultFontSize( | 683 page->GetSettings().SetAcceleratedCompositingEnabled(false); |
| 659 default_settings.GetDefaultFontSize()); | 684 |
| 660 page->GetSettings().SetDefaultFixedFontSize( | 685 // Because this page is detached, it can't get default font settings |
| 661 default_settings.GetDefaultFixedFontSize()); | 686 // from the embedder. Copy over font settings so we have sensible |
| 662 } | 687 // defaults. These settings are fixed and will not update if changed. |
| 688 if (!Page::OrdinaryPages().IsEmpty()) { |
| 689 Settings& default_settings = |
| 690 (*Page::OrdinaryPages().begin())->GetSettings(); |
| 691 page->GetSettings().GetGenericFontFamilySettings() = |
| 692 default_settings.GetGenericFontFamilySettings(); |
| 693 page->GetSettings().SetMinimumFontSize( |
| 694 default_settings.GetMinimumFontSize()); |
| 695 page->GetSettings().SetMinimumLogicalFontSize( |
| 696 default_settings.GetMinimumLogicalFontSize()); |
| 697 page->GetSettings().SetDefaultFontSize( |
| 698 default_settings.GetDefaultFontSize()); |
| 699 page->GetSettings().SetDefaultFixedFontSize( |
| 700 default_settings.GetDefaultFixedFontSize()); |
| 701 } |
| 663 } | 702 } |
| 664 | 703 |
| 665 LocalFrame* frame = nullptr; | 704 LocalFrame* frame = nullptr; |
| 666 { | 705 { |
| 667 TRACE_EVENT0("blink", "SVGImage::dataChanged::createFrame"); | 706 TRACE_EVENT0("blink", "SVGImage::dataChanged::createFrame"); |
| 668 frame = LocalFrame::Create(&dummy_local_frame_client, *page, 0); | 707 frame = LocalFrame::Create( |
| 708 new SVGImageLocalFrameClient(this->AsWeakPtr()), *page, 0); |
| 669 frame->SetView(FrameView::Create(*frame)); | 709 frame->SetView(FrameView::Create(*frame)); |
| 670 frame->Init(); | 710 frame->Init(); |
| 671 } | 711 } |
| 672 | 712 |
| 673 FrameLoader& loader = frame->Loader(); | 713 FrameLoader& loader = frame->Loader(); |
| 674 loader.ForceSandboxFlags(kSandboxAll); | 714 loader.ForceSandboxFlags(kSandboxAll); |
| 675 | 715 |
| 676 frame->View()->SetScrollbarsSuppressed(true); | 716 frame->View()->SetScrollbarsSuppressed(true); |
| 677 // SVG Images will always synthesize a viewBox, if it's not available, and | 717 // SVG Images will always synthesize a viewBox, if it's not available, and |
| 678 // thus never see scrollbars. | 718 // thus never see scrollbars. |
| 679 frame->View()->SetCanHaveScrollbars(false); | 719 frame->View()->SetCanHaveScrollbars(false); |
| 680 // SVG Images are transparent. | 720 // SVG Images are transparent. |
| 681 frame->View()->SetBaseBackgroundColor(Color::kTransparent); | 721 frame->View()->SetBaseBackgroundColor(Color::kTransparent); |
| 682 | 722 |
| 683 page_ = page; | 723 page_ = page; |
| 684 | 724 |
| 685 TRACE_EVENT0("blink", "SVGImage::dataChanged::load"); | 725 TRACE_EVENT0("blink", "SVGImage::dataChanged::load"); |
| 686 loader.Load(FrameLoadRequest( | 726 loader.Load(FrameLoadRequest( |
| 687 0, ResourceRequest(BlankURL()), | 727 0, ResourceRequest(BlankURL()), |
| 688 SubstituteData(Data(), AtomicString("image/svg+xml"), | 728 SubstituteData(Data(), AtomicString("image/svg+xml"), |
| 689 AtomicString("UTF-8"), KURL(), kForceSynchronousLoad))); | 729 AtomicString("UTF-8"), KURL(), kForceSynchronousLoad))); |
| 690 | 730 |
| 691 // Set the concrete object size before a container size is available. | 731 // Set the concrete object size before a container size is available. |
| 692 intrinsic_size_ = RoundedIntSize(ConcreteObjectSize(FloatSize( | 732 intrinsic_size_ = RoundedIntSize(ConcreteObjectSize(FloatSize( |
| 693 LayoutReplaced::kDefaultWidth, LayoutReplaced::kDefaultHeight))); | 733 LayoutReplaced::kDefaultWidth, LayoutReplaced::kDefaultHeight))); |
| 734 |
| 735 DCHECK(page_); |
| 736 switch (load_state_) { |
| 737 case kInDataChanged: |
| 738 load_state_ = kWaitingForAsyncLoadCompletion; |
| 739 return kSizeAvailableAndLoadingAsynchronously; |
| 740 |
| 741 case kLoadCompleted: |
| 742 return kSizeAvailable; |
| 743 |
| 744 case kDataChangedNotStarted: |
| 745 case kWaitingForAsyncLoadCompletion: |
| 746 CHECK(false); |
| 747 break; |
| 694 } | 748 } |
| 695 | 749 |
| 696 return page_ ? kSizeAvailable : kSizeUnavailable; | 750 NOTREACHED(); |
| 751 return kSizeAvailable; |
| 697 } | 752 } |
| 698 | 753 |
| 699 String SVGImage::FilenameExtension() const { | 754 String SVGImage::FilenameExtension() const { |
| 700 return "svg"; | 755 return "svg"; |
| 701 } | 756 } |
| 702 | 757 |
| 703 } // namespace blink | 758 } // namespace blink |
| OLD | NEW |