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/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 WebCore { 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().scheduleRefresh(); 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 WebCore 255