Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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/. */
6 #include "PlaceholderTxn.h"
7 #include "nsEditor.h"
8 #include "IMETextTxn.h"
9 #include "nsGkAtoms.h"
10 #include "mozilla/dom/Selection.h"
12 using namespace mozilla;
13 using namespace mozilla::dom;
15 PlaceholderTxn::PlaceholderTxn() : EditAggregateTxn(),
16 mAbsorb(true),
17 mForwarding(nullptr),
18 mIMETextTxn(nullptr),
19 mCommitted(false),
20 mStartSel(nullptr),
21 mEndSel(),
22 mEditor(nullptr)
23 {
24 }
26 NS_IMPL_CYCLE_COLLECTION_CLASS(PlaceholderTxn)
28 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PlaceholderTxn,
29 EditAggregateTxn)
30 tmp->mStartSel->DoUnlink();
31 tmp->mEndSel.DoUnlink();
32 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
34 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PlaceholderTxn,
35 EditAggregateTxn)
36 tmp->mStartSel->DoTraverse(cb);
37 tmp->mEndSel.DoTraverse(cb);
38 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
40 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PlaceholderTxn)
41 NS_INTERFACE_MAP_ENTRY(nsIAbsorbingTransaction)
42 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
43 NS_INTERFACE_MAP_END_INHERITING(EditAggregateTxn)
45 NS_IMPL_ADDREF_INHERITED(PlaceholderTxn, EditAggregateTxn)
46 NS_IMPL_RELEASE_INHERITED(PlaceholderTxn, EditAggregateTxn)
48 NS_IMETHODIMP
49 PlaceholderTxn::Init(nsIAtom* aName, nsSelectionState* aSelState,
50 nsEditor* aEditor)
51 {
52 NS_ENSURE_TRUE(aEditor && aSelState, NS_ERROR_NULL_POINTER);
54 mName = aName;
55 mStartSel = aSelState;
56 mEditor = aEditor;
57 return NS_OK;
58 }
60 NS_IMETHODIMP PlaceholderTxn::DoTransaction(void)
61 {
62 return NS_OK;
63 }
65 NS_IMETHODIMP PlaceholderTxn::UndoTransaction(void)
66 {
67 // undo txns
68 nsresult res = EditAggregateTxn::UndoTransaction();
69 NS_ENSURE_SUCCESS(res, res);
71 NS_ENSURE_TRUE(mStartSel, NS_ERROR_NULL_POINTER);
73 // now restore selection
74 nsCOMPtr<nsISelection> selection;
75 res = mEditor->GetSelection(getter_AddRefs(selection));
76 NS_ENSURE_SUCCESS(res, res);
77 NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
78 return mStartSel->RestoreSelection(selection);
79 }
82 NS_IMETHODIMP PlaceholderTxn::RedoTransaction(void)
83 {
84 // redo txns
85 nsresult res = EditAggregateTxn::RedoTransaction();
86 NS_ENSURE_SUCCESS(res, res);
88 // now restore selection
89 nsCOMPtr<nsISelection> selection;
90 res = mEditor->GetSelection(getter_AddRefs(selection));
91 NS_ENSURE_SUCCESS(res, res);
92 NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
93 return mEndSel.RestoreSelection(selection);
94 }
97 NS_IMETHODIMP PlaceholderTxn::Merge(nsITransaction *aTransaction, bool *aDidMerge)
98 {
99 NS_ENSURE_TRUE(aDidMerge && aTransaction, NS_ERROR_NULL_POINTER);
101 // set out param default value
102 *aDidMerge=false;
104 if (mForwarding)
105 {
106 NS_NOTREACHED("tried to merge into a placeholder that was in forwarding mode!");
107 return NS_ERROR_FAILURE;
108 }
110 // check to see if aTransaction is one of the editor's
111 // private transactions. If not, we want to avoid merging
112 // the foreign transaction into our placeholder since we
113 // don't know what it does.
115 nsCOMPtr<nsPIEditorTransaction> pTxn = do_QueryInterface(aTransaction);
116 NS_ENSURE_TRUE(pTxn, NS_OK); // it's foreign so just bail!
118 EditTxn *editTxn = (EditTxn*)aTransaction; //XXX: hack, not safe! need nsIEditTransaction!
119 // determine if this incoming txn is a placeholder txn
120 nsCOMPtr<nsIAbsorbingTransaction> plcTxn = do_QueryObject(editTxn);
122 // we are absorbing all txn's if mAbsorb is lit.
123 if (mAbsorb)
124 {
125 nsRefPtr<IMETextTxn> otherTxn;
126 if (NS_SUCCEEDED(aTransaction->QueryInterface(IMETextTxn::GetCID(), getter_AddRefs(otherTxn))) && otherTxn)
127 {
128 // special handling for IMETextTxn's: they need to merge with any previous
129 // IMETextTxn in this placeholder, if possible.
130 if (!mIMETextTxn)
131 {
132 // this is the first IME txn in the placeholder
133 mIMETextTxn =otherTxn;
134 AppendChild(editTxn);
135 }
136 else
137 {
138 bool didMerge;
139 mIMETextTxn->Merge(otherTxn, &didMerge);
140 if (!didMerge)
141 {
142 // it wouldn't merge. Earlier IME txn is already committed and will
143 // not absorb further IME txns. So just stack this one after it
144 // and remember it as a candidate for further merges.
145 mIMETextTxn =otherTxn;
146 AppendChild(editTxn);
147 }
148 }
149 }
150 else if (!plcTxn) // see bug 171243: just drop incoming placeholders on the floor.
151 { // their children will be swallowed by this preexisting one.
152 AppendChild(editTxn);
153 }
154 *aDidMerge = true;
155 // RememberEndingSelection();
156 // efficiency hack: no need to remember selection here, as we haven't yet
157 // finished the initial batch and we know we will be told when the batch ends.
158 // we can remeber the selection then.
159 }
160 else
161 { // merge typing or IME or deletion transactions if the selection matches
162 if (((mName.get() == nsGkAtoms::TypingTxnName) ||
163 (mName.get() == nsGkAtoms::IMETxnName) ||
164 (mName.get() == nsGkAtoms::DeleteTxnName))
165 && !mCommitted )
166 {
167 nsCOMPtr<nsIAbsorbingTransaction> plcTxn = do_QueryObject(editTxn);
168 if (plcTxn) {
169 nsCOMPtr<nsIAtom> atom;
170 plcTxn->GetTxnName(getter_AddRefs(atom));
171 if (atom && (atom == mName))
172 {
173 // check if start selection of next placeholder matches
174 // end selection of this placeholder
175 bool isSame;
176 plcTxn->StartSelectionEquals(&mEndSel, &isSame);
177 if (isSame)
178 {
179 mAbsorb = true; // we need to start absorbing again
180 plcTxn->ForwardEndBatchTo(this);
181 // AppendChild(editTxn);
182 // see bug 171243: we don't need to merge placeholders
183 // into placeholders. We just reactivate merging in the pre-existing
184 // placeholder and drop the new one on the floor. The EndPlaceHolderBatch()
185 // call on the new placeholder will be forwarded to this older one.
186 RememberEndingSelection();
187 *aDidMerge = true;
188 }
189 }
190 }
191 }
192 }
193 return NS_OK;
194 }
196 NS_IMETHODIMP PlaceholderTxn::GetTxnDescription(nsAString& aString)
197 {
198 aString.AssignLiteral("PlaceholderTxn: ");
200 if (mName)
201 {
202 nsAutoString name;
203 mName->ToString(name);
204 aString += name;
205 }
207 return NS_OK;
208 }
210 NS_IMETHODIMP PlaceholderTxn::GetTxnName(nsIAtom **aName)
211 {
212 return GetName(aName);
213 }
215 NS_IMETHODIMP PlaceholderTxn::StartSelectionEquals(nsSelectionState *aSelState, bool *aResult)
216 {
217 // determine if starting selection matches the given selection state.
218 // note that we only care about collapsed selections.
219 NS_ENSURE_TRUE(aResult && aSelState, NS_ERROR_NULL_POINTER);
220 if (!mStartSel->IsCollapsed() || !aSelState->IsCollapsed())
221 {
222 *aResult = false;
223 return NS_OK;
224 }
225 *aResult = mStartSel->IsEqual(aSelState);
226 return NS_OK;
227 }
229 NS_IMETHODIMP PlaceholderTxn::EndPlaceHolderBatch()
230 {
231 mAbsorb = false;
233 if (mForwarding)
234 {
235 nsCOMPtr<nsIAbsorbingTransaction> plcTxn = do_QueryReferent(mForwarding);
236 if (plcTxn) plcTxn->EndPlaceHolderBatch();
237 }
239 // remember our selection state.
240 return RememberEndingSelection();
241 }
243 NS_IMETHODIMP PlaceholderTxn::ForwardEndBatchTo(nsIAbsorbingTransaction *aForwardingAddress)
244 {
245 mForwarding = do_GetWeakReference(aForwardingAddress);
246 return NS_OK;
247 }
249 NS_IMETHODIMP PlaceholderTxn::Commit()
250 {
251 mCommitted = true;
252 return NS_OK;
253 }
255 NS_IMETHODIMP PlaceholderTxn::RememberEndingSelection()
256 {
257 nsRefPtr<Selection> selection = mEditor->GetSelection();
258 NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
259 mEndSel.SaveSelection(selection);
260 return NS_OK;
261 }