Home | History | Annotate | Download | only in frame
      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