5d49620f10418b896663096e7a244be2ab8b8a32
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / frame / History.cpp
1 /*
2  * Copyright (C) 2007 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  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "core/frame/History.h"
28
29 #include "bindings/core/v8/ExceptionState.h"
30 #include "core/dom/Document.h"
31 #include "core/dom/ExceptionCode.h"
32 #include "core/frame/LocalFrame.h"
33 #include "core/loader/DocumentLoader.h"
34 #include "core/loader/FrameLoader.h"
35 #include "core/loader/FrameLoaderClient.h"
36 #include "core/loader/HistoryItem.h"
37 #include "core/page/BackForwardClient.h"
38 #include "core/page/Page.h"
39 #include "platform/weborigin/KURL.h"
40 #include "platform/weborigin/SecurityOrigin.h"
41 #include "wtf/MainThread.h"
42
43 namespace blink {
44
45 History::History(LocalFrame* frame)
46     : DOMWindowProperty(frame)
47     , m_lastStateObjectRequested(nullptr)
48 {
49 }
50
51 void History::trace(Visitor* visitor)
52 {
53     DOMWindowProperty::trace(visitor);
54 }
55
56 unsigned History::length() const
57 {
58     if (!m_frame)
59         return 0;
60     if (!m_frame->page())
61         return 0;
62     return m_frame->page()->backForward().backForwardListCount();
63 }
64
65 SerializedScriptValue* History::state()
66 {
67     m_lastStateObjectRequested = stateInternal();
68     return m_lastStateObjectRequested.get();
69 }
70
71 SerializedScriptValue* History::stateInternal() const
72 {
73     if (!m_frame)
74         return 0;
75
76     if (HistoryItem* historyItem = m_frame->loader().currentItem())
77         return historyItem->stateObject();
78
79     return 0;
80 }
81
82 bool History::stateChanged() const
83 {
84     return m_lastStateObjectRequested != stateInternal();
85 }
86
87 bool History::isSameAsCurrentState(SerializedScriptValue* state) const
88 {
89     return state == stateInternal();
90 }
91
92 void History::back(ExecutionContext* context)
93 {
94     go(context, -1);
95 }
96
97 void History::forward(ExecutionContext* context)
98 {
99     go(context, 1);
100 }
101
102 void History::go(ExecutionContext* context, int distance)
103 {
104     if (!m_frame)
105         return;
106
107     ASSERT(isMainThread());
108     Document* activeDocument = toDocument(context);
109     if (!activeDocument)
110         return;
111
112     if (!activeDocument->canNavigate(*m_frame))
113         return;
114
115     m_frame->navigationScheduler().scheduleHistoryNavigation(distance);
116 }
117
118 KURL History::urlForState(const String& urlString)
119 {
120     Document* document = m_frame->document();
121
122     if (urlString.isNull())
123         return document->url();
124     if (urlString.isEmpty())
125         return document->baseURL();
126
127     return KURL(document->baseURL(), urlString);
128 }
129
130 void History::stateObjectAdded(PassRefPtr<SerializedScriptValue> data, const String& /* title */, const String& urlString, FrameLoadType type, ExceptionState& exceptionState)
131 {
132     if (!m_frame || !m_frame->page() || !m_frame->loader().documentLoader())
133         return;
134
135     KURL fullURL = urlForState(urlString);
136     if (!fullURL.isValid() || !m_frame->document()->securityOrigin()->canRequest(fullURL)) {
137         // We can safely expose the URL to JavaScript, as a) no redirection takes place: JavaScript already had this URL, b) JavaScript can only access a same-origin History object.
138         exceptionState.throwSecurityError("A history state object with URL '" + fullURL.elidedString() + "' cannot be created in a document with origin '" + m_frame->document()->securityOrigin()->toString() + "'.");
139         return;
140     }
141     m_frame->loader().updateForSameDocumentNavigation(fullURL, SameDocumentNavigationHistoryApi, data, type);
142 }
143
144 } // namespace blink