editor/libeditor/base/PlaceholderTxn.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

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.

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

mercurial