Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : /*
7 : * container for information saved in session history when the document
8 : * is not
9 : */
10 :
11 : #include "nsILayoutHistoryState.h"
12 : #include "nsWeakReference.h"
13 : #include "nsClassHashtable.h"
14 : #include "nsPresState.h"
15 : #include "mozilla/Attributes.h"
16 :
17 : class nsLayoutHistoryState final : public nsILayoutHistoryState,
18 : public nsSupportsWeakReference
19 : {
20 : public:
21 4 : nsLayoutHistoryState()
22 4 : : mScrollPositionOnly(false)
23 : {
24 4 : }
25 :
26 : NS_DECL_ISUPPORTS
27 : NS_DECL_NSILAYOUTHISTORYSTATE
28 :
29 : private:
30 1 : ~nsLayoutHistoryState() {}
31 : bool mScrollPositionOnly;
32 :
33 : nsClassHashtable<nsCStringHashKey,nsPresState> mStates;
34 : };
35 :
36 :
37 : already_AddRefed<nsILayoutHistoryState>
38 4 : NS_NewLayoutHistoryState()
39 : {
40 8 : RefPtr<nsLayoutHistoryState> state = new nsLayoutHistoryState();
41 8 : return state.forget();
42 : }
43 :
44 177 : NS_IMPL_ISUPPORTS(nsLayoutHistoryState,
45 : nsILayoutHistoryState,
46 : nsISupportsWeakReference)
47 :
48 : NS_IMETHODIMP
49 1 : nsLayoutHistoryState::GetHasStates(bool* aHasStates)
50 : {
51 1 : *aHasStates = HasStates();
52 1 : return NS_OK;
53 : }
54 :
55 : NS_IMETHODIMP
56 0 : nsLayoutHistoryState::GetKeys(uint32_t* aCount, char*** aKeys)
57 : {
58 0 : if (!HasStates()) {
59 0 : return NS_ERROR_FAILURE;
60 : }
61 :
62 : char** keys =
63 0 : static_cast<char**>(moz_xmalloc(sizeof(char*) * mStates.Count()));
64 0 : *aCount = mStates.Count();
65 0 : *aKeys = keys;
66 :
67 0 : for (auto iter = mStates.Iter(); !iter.Done(); iter.Next()) {
68 0 : *keys = ToNewCString(iter.Key());
69 0 : keys++;
70 : }
71 :
72 0 : return NS_OK;
73 : }
74 :
75 : NS_IMETHODIMP
76 0 : nsLayoutHistoryState::GetPresState(const nsACString& aKey,
77 : float* aScrollX, float* aScrollY,
78 : bool* aAllowScrollOriginDowngrade,
79 : float* aRes, bool* aScaleToRes)
80 : {
81 0 : nsPresState* state = GetState(nsCString(aKey));
82 :
83 0 : if (!state) {
84 0 : return NS_ERROR_FAILURE;
85 : }
86 :
87 0 : *aScrollX = state->GetScrollPosition().x;
88 0 : *aScrollY = state->GetScrollPosition().y;
89 0 : *aAllowScrollOriginDowngrade = state->GetAllowScrollOriginDowngrade();
90 0 : *aRes = state->GetResolution();
91 0 : *aScaleToRes = state->GetScaleToResolution();
92 :
93 0 : return NS_OK;
94 : }
95 :
96 : NS_IMETHODIMP
97 0 : nsLayoutHistoryState::AddNewPresState(const nsACString& aKey,
98 : float aScrollX, float aScrollY,
99 : bool aAllowScrollOriginDowngrade,
100 : float aRes, bool aScaleToRes)
101 : {
102 0 : nsPresState* newState = new nsPresState();
103 0 : newState->SetScrollState(nsPoint(aScrollX, aScrollY));
104 0 : newState->SetAllowScrollOriginDowngrade(aAllowScrollOriginDowngrade);
105 0 : newState->SetResolution(aRes);
106 0 : newState->SetScaleToResolution(aScaleToRes);
107 :
108 0 : mStates.Put(nsCString(aKey), newState);
109 :
110 0 : return NS_OK;
111 : }
112 :
113 : void
114 0 : nsLayoutHistoryState::AddState(const nsCString& aStateKey, nsPresState* aState)
115 : {
116 0 : mStates.Put(aStateKey, aState);
117 0 : }
118 :
119 : nsPresState*
120 4 : nsLayoutHistoryState::GetState(const nsCString& aKey)
121 : {
122 4 : nsPresState* state = nullptr;
123 4 : bool entryExists = mStates.Get(aKey, &state);
124 :
125 4 : if (entryExists && mScrollPositionOnly) {
126 : // Ensure any state that shouldn't be restored is removed
127 0 : state->ClearNonScrollState();
128 : }
129 :
130 4 : return state;
131 : }
132 :
133 : void
134 0 : nsLayoutHistoryState::RemoveState(const nsCString& aKey)
135 : {
136 0 : mStates.Remove(aKey);
137 0 : }
138 :
139 : bool
140 1 : nsLayoutHistoryState::HasStates()
141 : {
142 1 : return mStates.Count() != 0;
143 : }
144 :
145 : void
146 1 : nsLayoutHistoryState::SetScrollPositionOnly(const bool aFlag)
147 : {
148 1 : mScrollPositionOnly = aFlag;
149 1 : }
150 :
151 : void
152 0 : nsLayoutHistoryState::ResetScrollState()
153 : {
154 0 : for (auto iter = mStates.Iter(); !iter.Done(); iter.Next()) {
155 0 : nsPresState* state = iter.UserData();
156 0 : if (state) {
157 0 : state->SetScrollState(nsPoint(0, 0));
158 : }
159 : }
160 0 : }
|