/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// set out param default value
*aDidMerge = false;
if (mForwardingTransaction) {
MOZ_ASSERT_UNREACHABLE( "tried to merge into a placeholder that was in " "forwarding mode!"); return NS_ERROR_FAILURE;
}
RefPtr<EditTransactionBase> otherTransactionBase =
aOtherTransaction->GetAsEditTransactionBase(); if (!otherTransactionBase) {
MOZ_LOG(GetLogModule(), LogLevel::Debug,
("%p PlaceholderTransaction::%s(aOtherTransaction=%p) this={ " "mName=%s } returned false due to non edit transaction", this, __FUNCTION__, aOtherTransaction,
nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get())); return NS_OK;
}
// We are absorbing all transactions if mAbsorb is lit. if (mAbsorb) { if (CompositionTransaction* otherCompositionTransaction =
otherTransactionBase->GetAsCompositionTransaction()) { // special handling for CompositionTransaction's: they need to merge with // any previous CompositionTransaction in this placeholder, if possible. if (!mCompositionTransaction) { // this is the first IME txn in the placeholder
mCompositionTransaction = otherCompositionTransaction;
AppendChild(*otherCompositionTransaction);
} else { bool didMerge;
mCompositionTransaction->Merge(otherCompositionTransaction, &didMerge); if (!didMerge) { // it wouldn't merge. Earlier IME txn is already committed and will // not absorb further IME txns. So just stack this one after it // and remember it as a candidate for further merges.
mCompositionTransaction = otherCompositionTransaction;
AppendChild(*otherCompositionTransaction);
}
}
} else {
PlaceholderTransaction* otherPlaceholderTransaction =
otherTransactionBase->GetAsPlaceholderTransaction(); if (!otherPlaceholderTransaction) { // See bug 171243: just drop incoming placeholders on the floor. // Their children will be swallowed by this preexisting one.
AppendChild(*otherTransactionBase);
}
}
*aDidMerge = true; // RememberEndingSelection(); // efficiency hack: no need to remember selection here, as we haven't yet // finished the initial batch and we know we will be told when the batch // ends. we can remeber the selection then. return NS_OK;
}
// merge typing or IME or deletion transactions if the selection matches if (mCommitted ||
(mName != nsGkAtoms::TypingTxnName && mName != nsGkAtoms::IMETxnName &&
mName != nsGkAtoms::DeleteTxnName)) {
MOZ_LOG(GetLogModule(), LogLevel::Debug,
("%p PlaceholderTransaction::%s(aOtherTransaction=%p) this={ " "mName=%s } returned false due to non mergable transaction", this, __FUNCTION__, aOtherTransaction,
nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get())); return NS_OK;
}
PlaceholderTransaction* otherPlaceholderTransaction =
otherTransactionBase->GetAsPlaceholderTransaction(); if (!otherPlaceholderTransaction) {
MOZ_LOG(GetLogModule(), LogLevel::Debug,
("%p PlaceholderTransaction::%s(aOtherTransaction=%p) this={ " "mName=%s } returned false due to non placeholder transaction", this, __FUNCTION__, aOtherTransaction,
nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get())); return NS_OK;
}
RefPtr<nsAtom> otherTransactionName = otherPlaceholderTransaction->GetName(); if (!otherTransactionName || otherTransactionName == nsGkAtoms::_empty ||
otherTransactionName != mName) {
MOZ_LOG(GetLogModule(), LogLevel::Debug,
("%p PlaceholderTransaction::%s(aOtherTransaction=%p) this={ " "mName=%s } returned false due to non mergable placeholder " "transaction", this, __FUNCTION__, aOtherTransaction,
nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get())); return NS_OK;
}
// check if start selection of next placeholder matches // end selection of this placeholder // XXX Theese checks seem wrong. The ending selection is initialized with // actual Selection rather than expected Selection. Therefore, even when // web apps modifies Selection, we don't merge mergable transactions.
// If the new transaction's starting Selection is not a caret, we shouldn't be // merged with it because it's probably caused deleting the selection. if (!otherPlaceholderTransaction->mStartSel.HasOnlyCollapsedRange()) {
MOZ_LOG(GetLogModule(), LogLevel::Debug,
("%p PlaceholderTransaction::%s(aOtherTransaction=%p) this={ " "mName=%s } returned false due to not collapsed selection at " "start of new transactions", this, __FUNCTION__, aOtherTransaction,
nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get())); return NS_OK;
}
// If our ending Selection is not a caret, we should not be merged with it // because we probably changed format of a block or style of text. if (!mEndSel.HasOnlyCollapsedRange()) {
MOZ_LOG(GetLogModule(), LogLevel::Debug,
("%p PlaceholderTransaction::%s(aOtherTransaction=%p) this={ " "mName=%s } returned false due to not collapsed selection at end " "of previous transactions", this, __FUNCTION__, aOtherTransaction,
nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get())); return NS_OK;
}
// If the caret positions are now in different root nodes, e.g., the previous // caret position was removed from the DOM tree, this merge should not be // done. constbool isPreviousCaretPointInSameRootOfNewCaretPoint = [&]() {
nsINode* previousRootInCurrentDOMTree = mEndSel.GetCommonRootNode(); return previousRootInCurrentDOMTree &&
previousRootInCurrentDOMTree ==
otherPlaceholderTransaction->mStartSel.GetCommonRootNode();
}(); if (!isPreviousCaretPointInSameRootOfNewCaretPoint) {
MOZ_LOG(GetLogModule(), LogLevel::Debug,
("%p PlaceholderTransaction::%s(aOtherTransaction=%p) this={ " "mName=%s } returned false due to the caret points are in " "different root nodes", this, __FUNCTION__, aOtherTransaction,
nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get())); return NS_OK;
}
// If the caret points of end of us and start of new transaction are not same, // we shouldn't merge them. if (!otherPlaceholderTransaction->mStartSel.Equals(mEndSel)) {
MOZ_LOG(GetLogModule(), LogLevel::Debug,
("%p PlaceholderTransaction::%s(aOtherTransaction=%p) this={ " "mName=%s } returned false due to caret positions were different", this, __FUNCTION__, aOtherTransaction,
nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get())); return NS_OK;
}
mAbsorb = true; // we need to start absorbing again
otherPlaceholderTransaction->ForwardEndBatchTo(*this); // AppendChild(editTransactionBase); // see bug 171243: we don't need to merge placeholders // into placeholders. We just reactivate merging in the // pre-existing placeholder and drop the new one on the floor. The // EndPlaceHolderBatch() call on the new placeholder will be // forwarded to this older one.
DebugOnly<nsresult> rvIgnored = RememberEndingSelection();
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored), "PlaceholderTransaction::RememberEndingSelection() failed, but " "ignored");
*aDidMerge = true;
MOZ_LOG(GetLogModule(), LogLevel::Debug,
("%p PlaceholderTransaction::%s(aOtherTransaction=%p) this={ " "mName=%s } returned true", this, __FUNCTION__, aOtherTransaction,
nsAtomCString(mName ? mName.get() : nsGkAtoms::_empty).get())); return NS_OK;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.