f63b30b664d1bb23f11636bd2666f42a885f838d
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / html / HTMLFrameElementBase.cpp
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.
7  *
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.
12  *
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.
17  *
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.
22  */
23
24 #include "config.h"
25 #include "core/html/HTMLFrameElementBase.h"
26
27 #include "HTMLNames.h"
28 #include "bindings/v8/ScriptController.h"
29 #include "bindings/v8/ScriptEventListener.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/html/parser/HTMLParserIdioms.h"
35 #include "core/loader/FrameLoader.h"
36 #include "core/page/FocusController.h"
37 #include "core/page/Page.h"
38 #include "core/rendering/RenderPart.h"
39
40 namespace WebCore {
41
42 using namespace HTMLNames;
43
44 HTMLFrameElementBase::HTMLFrameElementBase(const QualifiedName& tagName, Document& document)
45     : HTMLFrameOwnerElement(tagName, document)
46     , m_scrolling(ScrollbarAuto)
47     , m_marginWidth(-1)
48     , m_marginHeight(-1)
49 {
50 }
51
52 bool HTMLFrameElementBase::isURLAllowed() const
53 {
54     if (m_URL.isEmpty())
55         return true;
56
57     const KURL& completeURL = document().completeURL(m_URL);
58
59     if (protocolIsJavaScript(completeURL)) {
60         Document* contentDoc = this->contentDocument();
61         if (contentDoc && !ScriptController::canAccessFromCurrentOrigin(contentDoc->frame()))
62             return false;
63     }
64
65     LocalFrame* parentFrame = document().frame();
66     if (parentFrame)
67         return parentFrame->isURLAllowed(completeURL);
68
69     return true;
70 }
71
72 void HTMLFrameElementBase::openURL(bool lockBackForwardList)
73 {
74     if (!isURLAllowed())
75         return;
76
77     if (m_URL.isEmpty())
78         m_URL = AtomicString(blankURL().string());
79
80     LocalFrame* parentFrame = document().frame();
81     if (!parentFrame)
82         return;
83
84     // Support for <frame src="javascript:string">
85     KURL scriptURL;
86     KURL url = document().completeURL(m_URL);
87     if (protocolIsJavaScript(m_URL)) {
88         scriptURL = url;
89         url = blankURL();
90     }
91
92     if (!loadOrRedirectSubframe(url, m_frameName, lockBackForwardList))
93         return;
94     if (!contentFrame() || scriptURL.isEmpty())
95         return;
96     contentFrame()->script().executeScriptIfJavaScriptURL(scriptURL);
97 }
98
99 void HTMLFrameElementBase::parseAttribute(const QualifiedName& name, const AtomicString& value)
100 {
101     if (name == srcdocAttr)
102         setLocation("about:srcdoc");
103     else if (name == srcAttr && !fastHasAttribute(srcdocAttr))
104         setLocation(stripLeadingAndTrailingHTMLSpaces(value));
105     else if (isIdAttributeName(name)) {
106         // Important to call through to base for the id attribute so the hasID bit gets set.
107         HTMLFrameOwnerElement::parseAttribute(name, value);
108         m_frameName = value;
109     } else if (name == nameAttr) {
110         m_frameName = value;
111         // FIXME: If we are already attached, this doesn't actually change the frame's name.
112         // FIXME: If we are already attached, this doesn't check for frame name
113         // conflicts and generate a unique frame name.
114     } else if (name == marginwidthAttr) {
115         m_marginWidth = value.toInt();
116         // FIXME: If we are already attached, this has no effect.
117     } else if (name == marginheightAttr) {
118         m_marginHeight = value.toInt();
119         // FIXME: If we are already attached, this has no effect.
120     } else if (name == scrollingAttr) {
121         // Auto and yes both simply mean "allow scrolling." No means "don't allow scrolling."
122         if (equalIgnoringCase(value, "auto") || equalIgnoringCase(value, "yes"))
123             m_scrolling = ScrollbarAuto;
124         else if (equalIgnoringCase(value, "no"))
125             m_scrolling = ScrollbarAlwaysOff;
126         // FIXME: If we are already attached, this has no effect.
127     } else if (name == onbeforeunloadAttr) {
128         // FIXME: should <frame> elements have beforeunload handlers?
129         setAttributeEventListener(EventTypeNames::beforeunload, createAttributeEventListener(this, name, value));
130     } else
131         HTMLFrameOwnerElement::parseAttribute(name, value);
132 }
133
134 void HTMLFrameElementBase::setNameAndOpenURL()
135 {
136     m_frameName = getNameAttribute();
137     openURL();
138 }
139
140 Node::InsertionNotificationRequest HTMLFrameElementBase::insertedInto(ContainerNode* insertionPoint)
141 {
142     HTMLFrameOwnerElement::insertedInto(insertionPoint);
143     return InsertionShouldCallDidNotifySubtreeInsertions;
144 }
145
146 void HTMLFrameElementBase::didNotifySubtreeInsertionsToDocument()
147 {
148     if (!document().frame())
149         return;
150
151     if (!SubframeLoadingDisabler::canLoadFrame(*this))
152         return;
153
154     setNameAndOpenURL();
155 }
156
157 void HTMLFrameElementBase::attach(const AttachContext& context)
158 {
159     HTMLFrameOwnerElement::attach(context);
160
161     if (RenderPart* part = renderPart()) {
162         if (LocalFrame* frame = contentFrame())
163             part->setWidget(frame->view());
164     }
165 }
166
167 KURL HTMLFrameElementBase::location() const
168 {
169     if (fastHasAttribute(srcdocAttr))
170         return KURL(ParsedURLString, "about:srcdoc");
171     return document().completeURL(getAttribute(srcAttr));
172 }
173
174 void HTMLFrameElementBase::setLocation(const String& str)
175 {
176     m_URL = AtomicString(str);
177
178     if (inDocument())
179         openURL(false);
180 }
181
182 bool HTMLFrameElementBase::supportsFocus() const
183 {
184     return true;
185 }
186
187 void HTMLFrameElementBase::setFocus(bool received)
188 {
189     HTMLFrameOwnerElement::setFocus(received);
190     if (Page* page = document().page()) {
191         if (received)
192             page->focusController().setFocusedFrame(contentFrame());
193         else if (page->focusController().focusedFrame() == contentFrame()) // Focus may have already been given to another frame, don't take it away.
194             page->focusController().setFocusedFrame(nullptr);
195     }
196 }
197
198 bool HTMLFrameElementBase::isURLAttribute(const Attribute& attribute) const
199 {
200     return attribute.name() == longdescAttr || attribute.name() == srcAttr
201         || HTMLFrameOwnerElement::isURLAttribute(attribute);
202 }
203
204 bool HTMLFrameElementBase::hasLegalLinkAttribute(const QualifiedName& name) const
205 {
206     return name == hrefAttr || HTMLFrameOwnerElement::hasLegalLinkAttribute(name);
207 }
208
209 bool HTMLFrameElementBase::isHTMLContentAttribute(const Attribute& attribute) const
210 {
211     return attribute.name() == srcdocAttr || HTMLFrameOwnerElement::isHTMLContentAttribute(attribute);
212 }
213
214 int HTMLFrameElementBase::width()
215 {
216     document().updateLayoutIgnorePendingStylesheets();
217     if (!renderBox())
218         return 0;
219     return renderBox()->width();
220 }
221
222 int HTMLFrameElementBase::height()
223 {
224     document().updateLayoutIgnorePendingStylesheets();
225     if (!renderBox())
226         return 0;
227     return renderBox()->height();
228 }
229
230 } // namespace WebCore