diff --git a/engine/core/core.gni b/engine/core/core.gni index 20f13e1e4e8..b09900da7a4 100644 --- a/engine/core/core.gni +++ b/engine/core/core.gni @@ -767,6 +767,8 @@ sky_core_files = [ "html/HTMLTemplateElement.h", "html/HTMLTitleElement.cpp", "html/HTMLTitleElement.h", + "html/HTMLIFrameElement.cpp", + "html/HTMLIFrameElement.h", "html/ImageData.cpp", "html/ImageData.h", "html/PublicURLManager.cpp", @@ -1053,6 +1055,7 @@ sky_core_files = [ "rendering/RenderLineBoxList.cpp", "rendering/RenderObject.cpp", "rendering/RenderObjectChildList.cpp", + "rendering/RenderRemote.cpp", "rendering/RenderReplaced.cpp", "rendering/RenderSelectionInfo.h", "rendering/RenderText.cpp", @@ -1224,6 +1227,7 @@ core_idl_files = get_path_info([ "html/HTMLContentElement.idl", "html/HTMLDocument.idl", "html/HTMLElement.idl", + "html/HTMLIFrameElement.idl", "html/HTMLImageElement.idl", "html/HTMLImportElement.idl", "html/HTMLScriptElement.idl", diff --git a/engine/core/html/HTMLIFrameElement.cpp b/engine/core/html/HTMLIFrameElement.cpp new file mode 100644 index 00000000000..0885e331baf --- /dev/null +++ b/engine/core/html/HTMLIFrameElement.cpp @@ -0,0 +1,65 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "config.h" +#include "core/html/HTMLIFrameElement.h" + +#include "core/HTMLNames.h" +#include "core/frame/LocalFrame.h" +#include "core/html/parser/HTMLParserIdioms.h" +#include "core/loader/FrameLoaderClient.h" +#include "core/rendering/RenderRemote.h" + +namespace blink { + +PassRefPtr HTMLIFrameElement::create(Document& document) +{ + return adoptRef(new HTMLIFrameElement(document)); +} + +HTMLIFrameElement::HTMLIFrameElement(Document& document) + : HTMLElement(HTMLNames::iframeTag, document) +{ +} + +HTMLIFrameElement::~HTMLIFrameElement() +{ +} + +Node::InsertionNotificationRequest HTMLIFrameElement::insertedInto(ContainerNode* insertionPoint) +{ + InsertionNotificationRequest result = HTMLElement::insertedInto(insertionPoint); + if (insertionPoint->inDocument()) + createView(); + return result; +} + +void HTMLIFrameElement::removedFrom(ContainerNode* insertionPoint) +{ + HTMLElement::removedFrom(insertionPoint); + if (insertionPoint->inDocument()) { + // TODO(mpcomplete): Tear down the mojo View. + } +} + +RenderObject* HTMLIFrameElement::createRenderer(RenderStyle* style) +{ + return new RenderRemote(this); +} + +void HTMLIFrameElement::createView() +{ + String urlString = stripLeadingAndTrailingHTMLSpaces(getAttribute(HTMLNames::srcAttr)); + if (urlString.isEmpty()) + urlString = blankURL().string(); + + LocalFrame* parentFrame = document().frame(); + if (!parentFrame) + return; + + KURL url = document().completeURL(urlString); + parentFrame->loaderClient()->createView(url); +} + +} diff --git a/engine/core/html/HTMLIFrameElement.h b/engine/core/html/HTMLIFrameElement.h new file mode 100644 index 00000000000..577f4b1d476 --- /dev/null +++ b/engine/core/html/HTMLIFrameElement.h @@ -0,0 +1,36 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef HTMLIFrameElement_h +#define HTMLIFrameElement_h + +#include "core/HTMLNames.h" +#include "core/dom/DOMURLUtils.h" +#include "core/dom/Document.h" +#include "core/html/HTMLElement.h" + +namespace blink { + +class HTMLIFrameElement : public HTMLElement { + DEFINE_WRAPPERTYPEINFO(); +public: + static PassRefPtr create(Document&); + + virtual ~HTMLIFrameElement(); + +private: + explicit HTMLIFrameElement(Document&); + + virtual RenderObject* createRenderer(RenderStyle* style) override; + + virtual InsertionNotificationRequest insertedInto(ContainerNode*) override; + virtual void removedFrom(ContainerNode*) override; + +private: + void createView(); +}; + +} // namespace blink + +#endif // HTMLIFrameElement_h diff --git a/engine/core/html/HTMLIFrameElement.idl b/engine/core/html/HTMLIFrameElement.idl new file mode 100644 index 00000000000..11fbc31f93b --- /dev/null +++ b/engine/core/html/HTMLIFrameElement.idl @@ -0,0 +1,6 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +interface HTMLIFrameElement : HTMLElement { +}; diff --git a/engine/core/html/HTMLTagNames.in b/engine/core/html/HTMLTagNames.in index 81f1e5a2902..418ab21abd2 100644 --- a/engine/core/html/HTMLTagNames.in +++ b/engine/core/html/HTMLTagNames.in @@ -4,6 +4,7 @@ fallbackInterfaceName="HTMLElement" a interfaceName=HTMLAnchorElement canvas content interfaceName=HTMLContentElement +iframe interfaceName=HTMLIFrameElement img interfaceName=HTMLImageElement, constructorNeedsCreatedByParser import script diff --git a/engine/core/loader/EmptyClients.h b/engine/core/loader/EmptyClients.h index 74309c96d9b..e29586b314f 100644 --- a/engine/core/loader/EmptyClients.h +++ b/engine/core/loader/EmptyClients.h @@ -130,6 +130,7 @@ public: virtual void didStopLoading() override { } virtual void loadURLExternally(const ResourceRequest&, NavigationPolicy, const String& = String()) override { } + virtual void createView(const KURL&) override {} virtual void transitionToCommittedForNewPage() override { } diff --git a/engine/core/loader/FrameLoaderClient.h b/engine/core/loader/FrameLoaderClient.h index dd9c9e7afcb..ebce8059db8 100644 --- a/engine/core/loader/FrameLoaderClient.h +++ b/engine/core/loader/FrameLoaderClient.h @@ -87,6 +87,9 @@ namespace blink { virtual void loadURLExternally(const ResourceRequest&, NavigationPolicy, const String& suggestedName = String()) = 0; + // TODO(mpcomplete): return surface ID? + virtual void createView(const KURL&) = 0; + // Transmits the change in the set of watched CSS selectors property // that match any element on the frame. virtual void selectorMatchChanged(const Vector& addedSelectors, const Vector& removedSelectors) = 0; diff --git a/engine/core/rendering/RenderRemote.cpp b/engine/core/rendering/RenderRemote.cpp new file mode 100644 index 00000000000..1ee502b0679 --- /dev/null +++ b/engine/core/rendering/RenderRemote.cpp @@ -0,0 +1,40 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "config.h" + +#include "core/rendering/RenderRemote.h" + +#include "core/editing/FrameSelection.h" +#include "core/html/HTMLIFrameElement.h" +#include "core/rendering/PaintInfo.h" +#include "platform/geometry/LayoutPoint.h" + +namespace blink { + +RenderRemote::RenderRemote(HTMLIFrameElement* view) + : RenderReplaced(view) +{ +} + +RenderRemote::~RenderRemote() +{ +} + +void RenderRemote::paintReplaced(PaintInfo& paintInfo, + const LayoutPoint& paintOffset) { + // Draw a gray background. This should be painted over by the actual + // content. + // TODO(mpcomplete): figure out what we should actually do here. + GraphicsContext* context = paintInfo.context; + + IntRect paintRect = pixelSnappedIntRect(LayoutRect( + paintOffset.x(), paintOffset.y(), contentWidth(), contentHeight())); + context->setStrokeStyle(SolidStroke); + context->setStrokeColor(Color::lightGray); + context->setFillColor(Color::darkGray); + context->drawRect(paintRect); +} + +} // namespace blink diff --git a/engine/core/rendering/RenderRemote.h b/engine/core/rendering/RenderRemote.h new file mode 100644 index 00000000000..08221160047 --- /dev/null +++ b/engine/core/rendering/RenderRemote.h @@ -0,0 +1,26 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef RenderRemote_h +#define RenderRemote_h + +#include "core/rendering/RenderReplaced.h" + +namespace blink { + +class HTMLIFrameElement; + +class RenderRemote : public RenderReplaced { +public: + explicit RenderRemote(HTMLIFrameElement*); + virtual ~RenderRemote(); + +private: + virtual LayerType layerTypeRequired() const override { return NormalLayer; } + virtual void paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset); +}; + +} // namespace blink + +#endif // RenderRemote_h diff --git a/engine/public/web/WebFrameClient.h b/engine/public/web/WebFrameClient.h index 5b5ede4b7cf..3409dd25e59 100644 --- a/engine/public/web/WebFrameClient.h +++ b/engine/public/web/WebFrameClient.h @@ -70,6 +70,8 @@ public: // frameDetached(). virtual WebFrame* createChildFrame(WebLocalFrame* parent, const WebString& frameName) { return 0; } + virtual void createChildView(const WebURL& url) { } + // This frame has been detached from the view, but has not been closed yet. virtual void frameDetached(WebFrame*) { } diff --git a/engine/web/FrameLoaderClientImpl.cpp b/engine/web/FrameLoaderClientImpl.cpp index 06740dcdb2e..5c835c52b42 100644 --- a/engine/web/FrameLoaderClientImpl.cpp +++ b/engine/web/FrameLoaderClientImpl.cpp @@ -37,6 +37,7 @@ #include "core/events/MouseEvent.h" #include "core/frame/FrameView.h" #include "core/frame/Settings.h" +#include "core/html/HTMLIFrameElement.h" #include "core/page/Chrome.h" #include "core/page/EventHandler.h" #include "core/page/Page.h" @@ -250,6 +251,13 @@ void FrameLoaderClientImpl::loadURLExternally(const ResourceRequest& request, Na } } +void FrameLoaderClientImpl::createView(const KURL& url) +{ + if (m_webFrame->client()) { + m_webFrame->client()->createChildView(url); + } +} + void FrameLoaderClientImpl::selectorMatchChanged(const Vector& addedSelectors, const Vector& removedSelectors) { if (WebFrameClient* client = m_webFrame->client()) diff --git a/engine/web/FrameLoaderClientImpl.h b/engine/web/FrameLoaderClientImpl.h index 4286c5db479..54582f6b7cc 100644 --- a/engine/web/FrameLoaderClientImpl.h +++ b/engine/web/FrameLoaderClientImpl.h @@ -73,6 +73,7 @@ public: virtual void didStopLoading() override; virtual void progressEstimateChanged(double progressEstimate) override; virtual void loadURLExternally(const ResourceRequest&, NavigationPolicy, const String& suggestedName = String()) override; + virtual void createView(const KURL&) override; virtual void selectorMatchChanged(const Vector& addedSelectors, const Vector& removedSelectors) override; virtual void transitionToCommittedForNewPage() override; virtual void didChangeScrollOffset() override; diff --git a/tests/lowlevel/iframe.sky b/tests/lowlevel/iframe.sky new file mode 100644 index 00000000000..67b1545fa4f --- /dev/null +++ b/tests/lowlevel/iframe.sky @@ -0,0 +1 @@ +
This is an element.
diff --git a/viewer/document_view.cc b/viewer/document_view.cc index 6eafdd25a4b..d34d253f8fe 100644 --- a/viewer/document_view.cc +++ b/viewer/document_view.cc @@ -151,6 +151,22 @@ blink::WebLayerTreeView* DocumentView::initializeLayerTreeView() { return web_layer_tree_view_impl_.get(); } +void DocumentView::createChildView(const blink::WebURL& url) { + if (!root_) + return; + + mojo::View* child = mojo::View::Create(root_->view_manager()); + root_->AddChild(child); + // TODO(mpcomplete): actual bounds. + mojo::Rect mojo_bounds; + mojo_bounds.x = 0; + mojo_bounds.y = 50; + mojo_bounds.width = 300; + mojo_bounds.height = 100; + child->SetBounds(mojo_bounds); + child->Embed(mojo::String::From(url.string().utf8())); +} + void DocumentView::frameDetached(blink::WebFrame* frame) { // |frame| is invalid after here. frame->close(); @@ -206,6 +222,10 @@ void DocumentView::OnViewBoundsChanged(mojo::View* view, void DocumentView::OnViewDestroyed(mojo::View* view) { DCHECK_EQ(view, root_); + + for (auto& child : root_->children()) + child->Destroy(); + delete this; } diff --git a/viewer/document_view.h b/viewer/document_view.h index aa36ebd2ba1..88abb6a9250 100644 --- a/viewer/document_view.h +++ b/viewer/document_view.h @@ -69,6 +69,7 @@ class DocumentView : public mojo::InterfaceImpl, virtual blink::WebLayerTreeView* initializeLayerTreeView(); // WebFrameClient methods: + void createChildView(const blink::WebURL&) override; void frameDetached(blink::WebFrame*) override; blink::WebNavigationPolicy decidePolicyForNavigation( const blink::WebFrameClient::NavigationPolicyInfo& info) override;