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 42namespace blink { 43 44Location::Location(LocalFrame* frame) 45 : DOMWindowProperty(frame) 46{ 47} 48 49void Location::trace(Visitor* visitor) 50{ 51 DOMWindowProperty::trace(visitor); 52} 53 54inline const KURL& Location::url() const 55{ 56 ASSERT(m_frame); 57 58 const KURL& url = m_frame->document()->url(); 59 if (!url.isValid()) 60 return blankURL(); // Use "about:blank" while the page is still loading (before we have a frame). 61 62 return url; 63} 64 65String Location::href() const 66{ 67 if (!m_frame) 68 return String(); 69 70 return url().string(); 71} 72 73String Location::protocol() const 74{ 75 if (!m_frame) 76 return String(); 77 return DOMURLUtilsReadOnly::protocol(url()); 78} 79 80String Location::host() const 81{ 82 if (!m_frame) 83 return String(); 84 return DOMURLUtilsReadOnly::host(url()); 85} 86 87String Location::hostname() const 88{ 89 if (!m_frame) 90 return String(); 91 return DOMURLUtilsReadOnly::hostname(url()); 92} 93 94String Location::port() const 95{ 96 if (!m_frame) 97 return String(); 98 return DOMURLUtilsReadOnly::port(url()); 99} 100 101String Location::pathname() const 102{ 103 if (!m_frame) 104 return String(); 105 return DOMURLUtilsReadOnly::pathname(url()); 106} 107 108String Location::search() const 109{ 110 if (!m_frame) 111 return String(); 112 return DOMURLUtilsReadOnly::search(url()); 113} 114 115String Location::origin() const 116{ 117 if (!m_frame) 118 return String(); 119 return DOMURLUtilsReadOnly::origin(url()); 120} 121 122PassRefPtrWillBeRawPtr<DOMStringList> Location::ancestorOrigins() const 123{ 124 RefPtrWillBeRawPtr<DOMStringList> origins = DOMStringList::create(); 125 if (!m_frame) 126 return origins.release(); 127 // FIXME: We do not yet have access to remote frame's origin. 128 for (Frame* frame = m_frame->tree().parent(); frame; frame = frame->tree().parent()) { 129 if (frame->isLocalFrame()) 130 origins->append(toLocalFrame(frame)->document()->securityOrigin()->toString()); 131 } 132 return origins.release(); 133} 134 135String Location::hash() const 136{ 137 if (!m_frame) 138 return String(); 139 140 return DOMURLUtilsReadOnly::hash(url()); 141} 142 143void Location::setHref(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& url) 144{ 145 if (!m_frame) 146 return; 147 setLocation(url, callingWindow, enteredWindow); 148} 149 150void Location::setProtocol(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& protocol, ExceptionState& exceptionState) 151{ 152 if (!m_frame) 153 return; 154 KURL url = m_frame->document()->url(); 155 if (!url.setProtocol(protocol)) { 156 exceptionState.throwDOMException(SyntaxError, "'" + protocol + "' is an invalid protocol."); 157 return; 158 } 159 setLocation(url.string(), callingWindow, enteredWindow); 160} 161 162void Location::setHost(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& host) 163{ 164 if (!m_frame) 165 return; 166 KURL url = m_frame->document()->url(); 167 url.setHostAndPort(host); 168 setLocation(url.string(), callingWindow, enteredWindow); 169} 170 171void Location::setHostname(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& hostname) 172{ 173 if (!m_frame) 174 return; 175 KURL url = m_frame->document()->url(); 176 url.setHost(hostname); 177 setLocation(url.string(), callingWindow, enteredWindow); 178} 179 180void Location::setPort(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& portString) 181{ 182 if (!m_frame) 183 return; 184 KURL url = m_frame->document()->url(); 185 url.setPort(portString); 186 setLocation(url.string(), callingWindow, enteredWindow); 187} 188 189void Location::setPathname(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& pathname) 190{ 191 if (!m_frame) 192 return; 193 KURL url = m_frame->document()->url(); 194 url.setPath(pathname); 195 setLocation(url.string(), callingWindow, enteredWindow); 196} 197 198void Location::setSearch(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& search) 199{ 200 if (!m_frame) 201 return; 202 KURL url = m_frame->document()->url(); 203 url.setQuery(search); 204 setLocation(url.string(), callingWindow, enteredWindow); 205} 206 207void Location::setHash(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& hash) 208{ 209 if (!m_frame) 210 return; 211 KURL url = m_frame->document()->url(); 212 String oldFragmentIdentifier = url.fragmentIdentifier(); 213 String newFragmentIdentifier = hash; 214 if (hash[0] == '#') 215 newFragmentIdentifier = hash.substring(1); 216 url.setFragmentIdentifier(newFragmentIdentifier); 217 // Note that by parsing the URL and *then* comparing fragments, we are 218 // comparing fragments post-canonicalization, and so this handles the 219 // cases where fragment identifiers are ignored or invalid. 220 if (equalIgnoringNullity(oldFragmentIdentifier, url.fragmentIdentifier())) 221 return; 222 setLocation(url.string(), callingWindow, enteredWindow); 223} 224 225void Location::assign(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& url) 226{ 227 if (!m_frame) 228 return; 229 setLocation(url, callingWindow, enteredWindow); 230} 231 232void Location::replace(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& url) 233{ 234 if (!m_frame) 235 return; 236 // Note: We call LocalDOMWindow::setLocation directly here because replace() always operates on the current frame. 237 m_frame->domWindow()->setLocation(url, callingWindow, enteredWindow, LockHistoryAndBackForwardList); 238} 239 240void Location::reload(LocalDOMWindow* callingWindow) 241{ 242 if (!m_frame) 243 return; 244 if (protocolIsJavaScript(m_frame->document()->url())) 245 return; 246 m_frame->navigationScheduler().scheduleReload(); 247} 248 249void Location::setLocation(const String& url, LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow) 250{ 251 ASSERT(m_frame); 252 LocalFrame* frame = m_frame->loader().findFrameForNavigation(nullAtom, callingWindow->document()); 253 if (!frame) 254 return; 255 frame->domWindow()->setLocation(url, callingWindow, enteredWindow); 256} 257 258} // namespace blink 259