Home | History | Annotate | Download | only in web
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "config.h"
      6 #include "public/web/WebFrame.h"
      7 
      8 #include "core/frame/RemoteFrame.h"
      9 #include "web/OpenedFrameTracker.h"
     10 #include "web/WebLocalFrameImpl.h"
     11 #include "web/WebRemoteFrameImpl.h"
     12 #include <algorithm>
     13 
     14 
     15 namespace blink {
     16 
     17 WebCore::Frame* toWebCoreFrame(const WebFrame* frame)
     18 {
     19     if (!frame)
     20         return 0;
     21 
     22     return frame->isWebLocalFrame()
     23         ? static_cast<WebCore::Frame*>(toWebLocalFrameImpl(frame)->frame())
     24         : toWebRemoteFrameImpl(frame)->frame();
     25 }
     26 
     27 void WebFrame::swap(WebFrame* frame)
     28 {
     29     using std::swap;
     30 
     31     if (m_parent) {
     32         if (m_parent->m_firstChild == this)
     33             m_parent->m_firstChild = frame;
     34         if (m_parent->m_lastChild == this)
     35             m_parent->m_lastChild = frame;
     36         swap(m_parent, frame->m_parent);
     37     }
     38     if (m_previousSibling) {
     39         m_previousSibling->m_nextSibling = frame;
     40         swap(m_previousSibling, frame->m_previousSibling);
     41     }
     42     if (m_nextSibling) {
     43         m_nextSibling->m_previousSibling = frame;
     44         swap(m_nextSibling, frame->m_nextSibling);
     45     }
     46     if (m_opener) {
     47         m_opener->m_openedFrameTracker->remove(this);
     48         m_opener->m_openedFrameTracker->add(frame);
     49         swap(m_opener, frame->m_opener);
     50     }
     51     if (!m_openedFrameTracker->isEmpty()) {
     52         m_openedFrameTracker->updateOpener(frame);
     53         frame->m_openedFrameTracker.reset(m_openedFrameTracker.release());
     54     }
     55 }
     56 
     57 WebFrame* WebFrame::opener() const
     58 {
     59     return m_opener;
     60 }
     61 
     62 void WebFrame::setOpener(WebFrame* opener)
     63 {
     64     if (m_opener)
     65         m_opener->m_openedFrameTracker->remove(this);
     66     if (opener)
     67         opener->m_openedFrameTracker->add(this);
     68     m_opener = opener;
     69 }
     70 
     71 void WebFrame::appendChild(WebFrame* child)
     72 {
     73     // FIXME: Original code asserts that the frames have the same Page. We
     74     // should add an equivalent check... figure out what.
     75     child->m_parent = this;
     76     WebFrame* oldLast = m_lastChild;
     77     m_lastChild = child;
     78 
     79     if (oldLast) {
     80         child->m_previousSibling = oldLast;
     81         oldLast->m_nextSibling = child;
     82     } else {
     83         m_firstChild = child;
     84     }
     85 
     86     toWebCoreFrame(this)->tree().invalidateScopedChildCount();
     87 }
     88 
     89 void WebFrame::removeChild(WebFrame* child)
     90 {
     91     child->m_parent = 0;
     92 
     93     if (m_firstChild == child)
     94         m_firstChild = child->m_nextSibling;
     95     else
     96         child->m_previousSibling->m_nextSibling = child->m_nextSibling;
     97 
     98     if (m_lastChild == child)
     99         m_lastChild = child->m_previousSibling;
    100     else
    101         child->m_nextSibling->m_previousSibling = child->m_previousSibling;
    102 
    103     child->m_previousSibling = child->m_nextSibling = 0;
    104 
    105     toWebCoreFrame(this)->tree().invalidateScopedChildCount();
    106 }
    107 
    108 WebFrame* WebFrame::parent() const
    109 {
    110     return m_parent;
    111 }
    112 
    113 WebFrame* WebFrame::top() const
    114 {
    115     WebFrame* frame = const_cast<WebFrame*>(this);
    116     for (WebFrame* parent = frame; parent; parent = parent->m_parent)
    117         frame = parent;
    118     return frame;
    119 }
    120 
    121 WebFrame* WebFrame::firstChild() const
    122 {
    123     return m_firstChild;
    124 }
    125 
    126 WebFrame* WebFrame::lastChild() const
    127 {
    128     return m_lastChild;
    129 }
    130 
    131 WebFrame* WebFrame::previousSibling() const
    132 {
    133     return m_previousSibling;
    134 }
    135 
    136 WebFrame* WebFrame::nextSibling() const
    137 {
    138     return m_nextSibling;
    139 }
    140 
    141 WebFrame* WebFrame::traversePrevious(bool wrap) const
    142 {
    143     WebCore::Frame* frame = toWebCoreFrame(this);
    144     if (!frame)
    145         return 0;
    146     return fromFrame(frame->tree().traversePreviousWithWrap(wrap));
    147 }
    148 
    149 WebFrame* WebFrame::traverseNext(bool wrap) const
    150 {
    151     WebCore::Frame* frame = toWebCoreFrame(this);
    152     if (!frame)
    153         return 0;
    154     return fromFrame(frame->tree().traverseNextWithWrap(wrap));
    155 }
    156 
    157 WebFrame* WebFrame::findChildByName(const WebString& name) const
    158 {
    159     WebCore::Frame* frame = toWebCoreFrame(this);
    160     if (!frame)
    161         return 0;
    162     // FIXME: It's not clear this should ever be called to find a remote frame.
    163     // Perhaps just disallow that completely?
    164     return fromFrame(frame->tree().child(name));
    165 }
    166 
    167 WebFrame* WebFrame::fromFrame(WebCore::Frame* frame)
    168 {
    169     if (!frame)
    170         return 0;
    171 
    172     if (frame->isLocalFrame())
    173         return WebLocalFrameImpl::fromFrame(toLocalFrame(*frame));
    174     return WebRemoteFrameImpl::fromFrame(toRemoteFrame(*frame));
    175 }
    176 
    177 WebFrame::WebFrame()
    178     : m_parent(0)
    179     , m_previousSibling(0)
    180     , m_nextSibling(0)
    181     , m_firstChild(0)
    182     , m_lastChild(0)
    183     , m_opener(0)
    184     , m_openedFrameTracker(new OpenedFrameTracker)
    185 {
    186 }
    187 
    188 WebFrame::~WebFrame()
    189 {
    190     m_openedFrameTracker.reset(0);
    191 }
    192 
    193 } // namespace blink
    194