Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / core / html / HTMLFrameElementBase.cpp
blob75865b6889054698df58dfc4a1fdf6b7b5a251e5
1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2000 Simon Hausmann (hausmann@kde.org)
5 * (C) 2001 Dirk Mueller (mueller@kde.org)
6 * Copyright (C) 2004, 2006, 2008, 2009 Apple Inc. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
24 #include "config.h"
25 #include "core/html/HTMLFrameElementBase.h"
27 #include "bindings/core/v8/ScriptController.h"
28 #include "bindings/core/v8/ScriptEventListener.h"
29 #include "core/HTMLNames.h"
30 #include "core/dom/Attribute.h"
31 #include "core/dom/Document.h"
32 #include "core/frame/FrameView.h"
33 #include "core/frame/LocalFrame.h"
34 #include "core/frame/RemoteFrame.h"
35 #include "core/frame/RemoteFrameView.h"
36 #include "core/html/parser/HTMLParserIdioms.h"
37 #include "core/layout/LayoutPart.h"
38 #include "core/loader/FrameLoader.h"
39 #include "core/page/FocusController.h"
40 #include "core/page/Page.h"
42 namespace blink {
44 using namespace HTMLNames;
46 HTMLFrameElementBase::HTMLFrameElementBase(const QualifiedName& tagName, Document& document)
47 : HTMLFrameOwnerElement(tagName, document)
48 , m_scrolling(ScrollbarAuto)
49 , m_marginWidth(-1)
50 , m_marginHeight(-1)
54 bool HTMLFrameElementBase::isURLAllowed() const
56 if (m_URL.isEmpty())
57 return true;
59 const KURL& completeURL = document().completeURL(m_URL);
61 if (protocolIsJavaScript(completeURL)) {
62 Document* contentDoc = this->contentDocument();
63 if (contentDoc && !ScriptController::canAccessFromCurrentOrigin(contentDoc->frame()))
64 return false;
67 LocalFrame* parentFrame = document().frame();
68 if (parentFrame)
69 return parentFrame->isURLAllowed(completeURL);
71 return true;
74 void HTMLFrameElementBase::openURL(bool replaceCurrentItem)
76 if (!isURLAllowed())
77 return;
79 if (m_URL.isEmpty())
80 m_URL = AtomicString(blankURL().string());
82 LocalFrame* parentFrame = document().frame();
83 if (!parentFrame)
84 return;
86 // Support for <frame src="javascript:string">
87 KURL scriptURL;
88 KURL url = document().completeURL(m_URL);
89 if (protocolIsJavaScript(m_URL)) {
90 scriptURL = url;
91 url = blankURL();
94 if (!loadOrRedirectSubframe(url, m_frameName, replaceCurrentItem))
95 return;
96 if (!contentFrame() || scriptURL.isEmpty() || !contentFrame()->isLocalFrame())
97 return;
98 toLocalFrame(contentFrame())->script().executeScriptIfJavaScriptURL(scriptURL);
101 void HTMLFrameElementBase::parseAttribute(const QualifiedName& name, const AtomicString& value)
103 if (name == srcdocAttr) {
104 if (!value.isNull()) {
105 setLocation("about:srcdoc");
106 } else {
107 const AtomicString& srcValue = fastGetAttribute(srcAttr);
108 if (!srcValue.isNull())
109 setLocation(stripLeadingAndTrailingHTMLSpaces(srcValue));
111 } else if (name == srcAttr && !fastHasAttribute(srcdocAttr)) {
112 setLocation(stripLeadingAndTrailingHTMLSpaces(value));
113 } else if (name == idAttr) {
114 // Important to call through to base for the id attribute so the hasID bit gets set.
115 HTMLFrameOwnerElement::parseAttribute(name, value);
116 m_frameName = value;
117 } else if (name == nameAttr) {
118 m_frameName = value;
119 // FIXME: If we are already attached, this doesn't actually change the frame's name.
120 // FIXME: If we are already attached, this doesn't check for frame name
121 // conflicts and generate a unique frame name.
122 } else if (name == marginwidthAttr) {
123 m_marginWidth = value.toInt();
124 // FIXME: If we are already attached, this has no effect.
125 } else if (name == marginheightAttr) {
126 m_marginHeight = value.toInt();
127 // FIXME: If we are already attached, this has no effect.
128 } else if (name == scrollingAttr) {
129 // Auto and yes both simply mean "allow scrolling." No means "don't allow scrolling."
130 if (equalIgnoringCase(value, "auto") || equalIgnoringCase(value, "yes"))
131 m_scrolling = ScrollbarAuto;
132 else if (equalIgnoringCase(value, "no"))
133 m_scrolling = ScrollbarAlwaysOff;
134 // FIXME: If we are already attached, this has no effect.
135 } else if (name == onbeforeunloadAttr) {
136 // FIXME: should <frame> elements have beforeunload handlers?
137 setAttributeEventListener(EventTypeNames::beforeunload, createAttributeEventListener(this, name, value, eventParameterName()));
138 } else {
139 HTMLFrameOwnerElement::parseAttribute(name, value);
143 void HTMLFrameElementBase::setNameAndOpenURL()
145 m_frameName = getNameAttribute();
146 openURL();
149 Node::InsertionNotificationRequest HTMLFrameElementBase::insertedInto(ContainerNode* insertionPoint)
151 HTMLFrameOwnerElement::insertedInto(insertionPoint);
152 return InsertionShouldCallDidNotifySubtreeInsertions;
155 void HTMLFrameElementBase::didNotifySubtreeInsertionsToDocument()
157 if (!document().frame())
158 return;
160 if (!SubframeLoadingDisabler::canLoadFrame(*this))
161 return;
163 setNameAndOpenURL();
166 void HTMLFrameElementBase::attach(const AttachContext& context)
168 HTMLFrameOwnerElement::attach(context);
170 if (layoutPart()) {
171 if (Frame* frame = contentFrame()) {
172 if (frame->isLocalFrame())
173 setWidget(toLocalFrame(frame)->view());
174 else if (frame->isRemoteFrame())
175 setWidget(toRemoteFrame(frame)->view());
180 void HTMLFrameElementBase::setLocation(const String& str)
182 m_URL = AtomicString(str);
184 if (inDocument())
185 openURL(false);
188 bool HTMLFrameElementBase::supportsFocus() const
190 return true;
193 void HTMLFrameElementBase::setFocus(bool received)
195 HTMLFrameOwnerElement::setFocus(received);
196 if (Page* page = document().page()) {
197 if (received)
198 page->focusController().setFocusedFrame(contentFrame());
199 else if (page->focusController().focusedFrame() == contentFrame()) // Focus may have already been given to another frame, don't take it away.
200 page->focusController().setFocusedFrame(nullptr);
204 bool HTMLFrameElementBase::isURLAttribute(const Attribute& attribute) const
206 return attribute.name() == longdescAttr || attribute.name() == srcAttr
207 || HTMLFrameOwnerElement::isURLAttribute(attribute);
210 bool HTMLFrameElementBase::hasLegalLinkAttribute(const QualifiedName& name) const
212 return name == srcAttr || HTMLFrameOwnerElement::hasLegalLinkAttribute(name);
215 bool HTMLFrameElementBase::isHTMLContentAttribute(const Attribute& attribute) const
217 return attribute.name() == srcdocAttr || HTMLFrameOwnerElement::isHTMLContentAttribute(attribute);
220 // FIXME: Remove this code once we have input routing in the browser
221 // process. See http://crbug.com/339659.
222 void HTMLFrameElementBase::defaultEventHandler(Event* event)
224 if (contentFrame() && contentFrame()->isRemoteFrame()) {
225 toRemoteFrame(contentFrame())->forwardInputEvent(event);
226 return;
228 HTMLFrameOwnerElement::defaultEventHandler(event);
231 } // namespace blink