• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "Location.h"
31 
32 #include "DOMWindow.h"
33 #include "ExceptionCode.h"
34 #include "Frame.h"
35 #include "FrameLoader.h"
36 #include "KURL.h"
37 
38 namespace WebCore {
39 
Location(Frame * frame)40 Location::Location(Frame* frame)
41     : m_frame(frame)
42 {
43 }
44 
disconnectFrame()45 void Location::disconnectFrame()
46 {
47     m_frame = 0;
48 }
49 
url() const50 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 
href() const61 String Location::href() const
62 {
63     if (!m_frame)
64         return String();
65 
66     return url().string();
67 }
68 
protocol() const69 String Location::protocol() const
70 {
71     if (!m_frame)
72         return String();
73 
74     return url().protocol() + ":";
75 }
76 
host() const77 String Location::host() const
78 {
79     if (!m_frame)
80         return String();
81 
82     // Note: this is the IE spec. The NS spec swaps the two, it says
83     // "The hostname property is the concatenation of the host and port properties, separated by a colon."
84     const KURL& url = this->url();
85     return url.hasPort() ? url.host() + ":" + String::number(url.port()) : url.host();
86 }
87 
hostname() const88 String Location::hostname() const
89 {
90     if (!m_frame)
91         return String();
92 
93     return url().host();
94 }
95 
port() const96 String Location::port() const
97 {
98     if (!m_frame)
99         return String();
100 
101     const KURL& url = this->url();
102     return url.hasPort() ? String::number(url.port()) : "";
103 }
104 
pathname() const105 String Location::pathname() const
106 {
107     if (!m_frame)
108         return String();
109 
110     const KURL& url = this->url();
111     return url.path().isEmpty() ? "/" : url.path();
112 }
113 
search() const114 String Location::search() const
115 {
116     if (!m_frame)
117         return String();
118 
119     const KURL& url = this->url();
120     return url.query().isEmpty() ? "" : "?" + url.query();
121 }
122 
origin() const123 String Location::origin() const
124 {
125     if (!m_frame)
126         return String();
127     return SecurityOrigin::create(url())->toString();
128 }
129 
hash() const130 String Location::hash() const
131 {
132     if (!m_frame)
133         return String();
134 
135     const String& fragmentIdentifier = url().fragmentIdentifier();
136     return fragmentIdentifier.isEmpty() ? "" : "#" + fragmentIdentifier;
137 }
138 
getParameter(const String & name) const139 String Location::getParameter(const String& name) const
140 {
141     if (!m_frame)
142         return String();
143 
144     ParsedURLParameters parameters;
145     url().copyParsedQueryTo(parameters);
146     return parameters.get(name);
147 }
148 
setHref(const String & urlString,DOMWindow * activeWindow,DOMWindow * firstWindow)149 void Location::setHref(const String& urlString, DOMWindow* activeWindow, DOMWindow* firstWindow)
150 {
151     if (!m_frame)
152         return;
153     m_frame->domWindow()->setLocation(urlString, activeWindow, firstWindow);
154 }
155 
setProtocol(const String & protocol,DOMWindow * activeWindow,DOMWindow * firstWindow,ExceptionCode & ec)156 void Location::setProtocol(const String& protocol, DOMWindow* activeWindow, DOMWindow* firstWindow, ExceptionCode& ec)
157 {
158     if (!m_frame)
159         return;
160     KURL url = m_frame->document()->url();
161     if (!url.setProtocol(protocol)) {
162         ec = SYNTAX_ERR;
163         return;
164     }
165     m_frame->domWindow()->setLocation(url.string(), activeWindow, firstWindow);
166 }
167 
setHost(const String & host,DOMWindow * activeWindow,DOMWindow * firstWindow)168 void Location::setHost(const String& host, DOMWindow* activeWindow, DOMWindow* firstWindow)
169 {
170     if (!m_frame)
171         return;
172     KURL url = m_frame->document()->url();
173     url.setHostAndPort(host);
174     m_frame->domWindow()->setLocation(url.string(), activeWindow, firstWindow);
175 }
176 
setHostname(const String & hostname,DOMWindow * activeWindow,DOMWindow * firstWindow)177 void Location::setHostname(const String& hostname, DOMWindow* activeWindow, DOMWindow* firstWindow)
178 {
179     if (!m_frame)
180         return;
181     KURL url = m_frame->document()->url();
182     url.setHost(hostname);
183     m_frame->domWindow()->setLocation(url.string(), activeWindow, firstWindow);
184 }
185 
setPort(const String & portString,DOMWindow * activeWindow,DOMWindow * firstWindow)186 void Location::setPort(const String& portString, DOMWindow* activeWindow, DOMWindow* firstWindow)
187 {
188     if (!m_frame)
189         return;
190     KURL url = m_frame->document()->url();
191     int port = portString.toInt();
192     if (port < 0 || port > 0xFFFF || portString.isEmpty())
193         url.removePort();
194     else
195         url.setPort(port);
196     m_frame->domWindow()->setLocation(url.string(), activeWindow, firstWindow);
197 }
198 
setPathname(const String & pathname,DOMWindow * activeWindow,DOMWindow * firstWindow)199 void Location::setPathname(const String& pathname, DOMWindow* activeWindow, DOMWindow* firstWindow)
200 {
201     if (!m_frame)
202         return;
203     KURL url = m_frame->document()->url();
204     url.setPath(pathname);
205     m_frame->domWindow()->setLocation(url.string(), activeWindow, firstWindow);
206 }
207 
setSearch(const String & search,DOMWindow * activeWindow,DOMWindow * firstWindow)208 void Location::setSearch(const String& search, DOMWindow* activeWindow, DOMWindow* firstWindow)
209 {
210     if (!m_frame)
211         return;
212     KURL url = m_frame->document()->url();
213     url.setQuery(search);
214     m_frame->domWindow()->setLocation(url.string(), activeWindow, firstWindow);
215 }
216 
setHash(const String & hash,DOMWindow * activeWindow,DOMWindow * firstWindow)217 void Location::setHash(const String& hash, DOMWindow* activeWindow, DOMWindow* firstWindow)
218 {
219     if (!m_frame)
220         return;
221     KURL url = m_frame->document()->url();
222     String oldFragmentIdentifier = url.fragmentIdentifier();
223     String newFragmentIdentifier = hash;
224     if (hash[0] == '#')
225         newFragmentIdentifier = hash.substring(1);
226     url.setFragmentIdentifier(newFragmentIdentifier);
227     // Note that by parsing the URL and *then* comparing fragments, we are
228     // comparing fragments post-canonicalization, and so this handles the
229     // cases where fragment identifiers are ignored or invalid.
230     if (equalIgnoringNullity(oldFragmentIdentifier, url.fragmentIdentifier()))
231         return;
232     m_frame->domWindow()->setLocation(url.string(), activeWindow, firstWindow);
233 }
234 
assign(const String & urlString,DOMWindow * activeWindow,DOMWindow * firstWindow)235 void Location::assign(const String& urlString, DOMWindow* activeWindow, DOMWindow* firstWindow)
236 {
237     if (!m_frame)
238         return;
239     m_frame->domWindow()->setLocation(urlString, activeWindow, firstWindow);
240 }
241 
replace(const String & urlString,DOMWindow * activeWindow,DOMWindow * firstWindow)242 void Location::replace(const String& urlString, DOMWindow* activeWindow, DOMWindow* firstWindow)
243 {
244     if (!m_frame)
245         return;
246     m_frame->domWindow()->setLocation(urlString, activeWindow, firstWindow, LockHistoryAndBackForwardList);
247 }
248 
reload(DOMWindow * activeWindow)249 void Location::reload(DOMWindow* activeWindow)
250 {
251     if (!m_frame)
252         return;
253     // FIXME: It's not clear this cross-origin security check is valuable.
254     // We allow one page to change the location of another. Why block attempts to reload?
255     // Other location operations simply block use of JavaScript URLs cross origin.
256     DOMWindow* targetWindow = m_frame->domWindow();
257     if (!activeWindow->securityOrigin()->canAccess(targetWindow->securityOrigin())) {
258         targetWindow->printErrorMessage(targetWindow->crossDomainAccessErrorMessage(activeWindow));
259         return;
260     }
261     if (protocolIsJavaScript(m_frame->document()->url()))
262         return;
263     m_frame->navigationScheduler()->scheduleRefresh();
264 }
265 
266 } // namespace WebCore
267