e651dffa7f852e1f486a4dcb5f482e041a4f5b99
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / frame / Location.cpp
1 /*
2  * Copyright (C) 2008, 2010 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "config.h"
30 #include "core/frame/Location.h"
31
32 #include "bindings/core/v8/ExceptionState.h"
33 #include "core/dom/DOMURLUtilsReadOnly.h"
34 #include "core/dom/Document.h"
35 #include "core/dom/ExceptionCode.h"
36 #include "core/frame/LocalDOMWindow.h"
37 #include "core/frame/LocalFrame.h"
38 #include "core/loader/FrameLoader.h"
39 #include "platform/weborigin/KURL.h"
40 #include "platform/weborigin/SecurityOrigin.h"
41
42 namespace blink {
43
44 Location::Location(LocalFrame* frame)
45     : DOMWindowProperty(frame)
46 {
47     ScriptWrappable::init(this);
48 }
49
50 inline const KURL& Location::url() const
51 {
52     ASSERT(m_frame);
53
54     const KURL& url = m_frame->document()->url();
55     if (!url.isValid())
56         return blankURL(); // Use "about:blank" while the page is still loading (before we have a frame).
57
58     return url;
59 }
60
61 String Location::href() const
62 {
63     if (!m_frame)
64         return String();
65
66     return url().string();
67 }
68
69 String Location::protocol() const
70 {
71     if (!m_frame)
72         return String();
73     return DOMURLUtilsReadOnly::protocol(url());
74 }
75
76 String Location::host() const
77 {
78     if (!m_frame)
79         return String();
80     return DOMURLUtilsReadOnly::host(url());
81 }
82
83 String Location::hostname() const
84 {
85     if (!m_frame)
86         return String();
87     return DOMURLUtilsReadOnly::hostname(url());
88 }
89
90 String Location::port() const
91 {
92     if (!m_frame)
93         return String();
94     return DOMURLUtilsReadOnly::port(url());
95 }
96
97 String Location::pathname() const
98 {
99     if (!m_frame)
100         return String();
101     return DOMURLUtilsReadOnly::pathname(url());
102 }
103
104 String Location::search() const
105 {
106     if (!m_frame)
107         return String();
108     return DOMURLUtilsReadOnly::search(url());
109 }
110
111 String Location::origin() const
112 {
113     if (!m_frame)
114         return String();
115     return DOMURLUtilsReadOnly::origin(url());
116 }
117
118 PassRefPtrWillBeRawPtr<DOMStringList> Location::ancestorOrigins() const
119 {
120     RefPtrWillBeRawPtr<DOMStringList> origins = DOMStringList::create();
121     if (!m_frame)
122         return origins.release();
123     // FIXME: We do not yet have access to remote frame's origin.
124     for (Frame* frame = m_frame->tree().parent(); frame; frame = frame->tree().parent()) {
125         if (frame->isLocalFrame())
126             origins->append(toLocalFrame(frame)->document()->securityOrigin()->toString());
127     }
128     return origins.release();
129 }
130
131 String Location::hash() const
132 {
133     if (!m_frame)
134         return String();
135
136     return DOMURLUtilsReadOnly::hash(url());
137 }
138
139 void Location::setHref(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& url)
140 {
141     if (!m_frame)
142         return;
143     setLocation(url, callingWindow, enteredWindow);
144 }
145
146 void Location::setProtocol(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& protocol, ExceptionState& exceptionState)
147 {
148     if (!m_frame)
149         return;
150     KURL url = m_frame->document()->url();
151     if (!url.setProtocol(protocol)) {
152         exceptionState.throwDOMException(SyntaxError, "'" + protocol + "' is an invalid protocol.");
153         return;
154     }
155     setLocation(url.string(), callingWindow, enteredWindow);
156 }
157
158 void Location::setHost(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& host)
159 {
160     if (!m_frame)
161         return;
162     KURL url = m_frame->document()->url();
163     url.setHostAndPort(host);
164     setLocation(url.string(), callingWindow, enteredWindow);
165 }
166
167 void Location::setHostname(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& hostname)
168 {
169     if (!m_frame)
170         return;
171     KURL url = m_frame->document()->url();
172     url.setHost(hostname);
173     setLocation(url.string(), callingWindow, enteredWindow);
174 }
175
176 void Location::setPort(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& portString)
177 {
178     if (!m_frame)
179         return;
180     KURL url = m_frame->document()->url();
181     url.setPort(portString);
182     setLocation(url.string(), callingWindow, enteredWindow);
183 }
184
185 void Location::setPathname(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& pathname)
186 {
187     if (!m_frame)
188         return;
189     KURL url = m_frame->document()->url();
190     url.setPath(pathname);
191     setLocation(url.string(), callingWindow, enteredWindow);
192 }
193
194 void Location::setSearch(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& search)
195 {
196     if (!m_frame)
197         return;
198     KURL url = m_frame->document()->url();
199     url.setQuery(search);
200     setLocation(url.string(), callingWindow, enteredWindow);
201 }
202
203 void Location::setHash(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& hash)
204 {
205     if (!m_frame)
206         return;
207     KURL url = m_frame->document()->url();
208     String oldFragmentIdentifier = url.fragmentIdentifier();
209     String newFragmentIdentifier = hash;
210     if (hash[0] == '#')
211         newFragmentIdentifier = hash.substring(1);
212     url.setFragmentIdentifier(newFragmentIdentifier);
213     // Note that by parsing the URL and *then* comparing fragments, we are
214     // comparing fragments post-canonicalization, and so this handles the
215     // cases where fragment identifiers are ignored or invalid.
216     if (equalIgnoringNullity(oldFragmentIdentifier, url.fragmentIdentifier()))
217         return;
218     setLocation(url.string(), callingWindow, enteredWindow);
219 }
220
221 void Location::assign(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& url)
222 {
223     if (!m_frame)
224         return;
225     setLocation(url, callingWindow, enteredWindow);
226 }
227
228 void Location::replace(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& url)
229 {
230     if (!m_frame)
231         return;
232     // Note: We call LocalDOMWindow::setLocation directly here because replace() always operates on the current frame.
233     m_frame->domWindow()->setLocation(url, callingWindow, enteredWindow, LockHistoryAndBackForwardList);
234 }
235
236 void Location::reload(LocalDOMWindow* callingWindow)
237 {
238     if (!m_frame)
239         return;
240     if (protocolIsJavaScript(m_frame->document()->url()))
241         return;
242     m_frame->navigationScheduler().scheduleReload();
243 }
244
245 void Location::setLocation(const String& url, LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow)
246 {
247     ASSERT(m_frame);
248     LocalFrame* frame = m_frame->loader().findFrameForNavigation(nullAtom, callingWindow->document());
249     if (!frame)
250         return;
251     frame->domWindow()->setLocation(url, callingWindow, enteredWindow);
252 }
253
254 } // namespace blink