mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:30:27 +00:00
e39f9f88f7
- Bug 1152171 part 2 - Rename AnimationTimeline to DocumentTimeline; r=smaug (26c118319) - Bug 1152171 part 3 - Update web-platform-tests expectations; r=jgraham (b7b4032aa) - Bug 1153734 part 1 - Remove AnimationEffect; r=smaug (9cf67a02e) - Bug 1153734 part 2 - Rename Animation to KeyframeEffectReadonly; r=smaug (b69556ee6) - Bug 1153734 part 3 - Rename AnimationPlayer.source to AnimationPlayer.effect; r=smaug (50d3130ee) - Bug 1153734 part 4 - Rename other uses of 'source' and 'source content'; r=jwatt (b02c4ba36) - Bug 1153734 part 5 - Add AnimationEffectReadonly as a superinterface of KeyframeEffectReadonly; r=smaug (c3395d3f5) - Bug 1149990 - Support replaying of finished CSS transitions by supporting setting of currentTime/startTime. r=birtles (3fb2cb401) - Bug 1154615 part 1 - Rename AnimationPlayer to Animation in WebIDL; r=smaug (6c2125b49) - Bug 1154615 part 2 - Rename PendingPlayerTracker to PendingAnimationTracker; r=jwatt (8d6804def) - Bug 1154615 part 3 - Rename internal members of PendingAnimationTracker; r=jwatt (f348f6355) - Bug 1154615 part 4 - Rename references to players in dom/animation; r=jwatt (0250572e8) - Bug 1117603 part 1 - Don't assume style rules have been refreshed in GetAnimationRule; r=dbaron (a5d340d0f) - remove kungFuDeathGrip (49df758e6) - Bug 1117603 part 2 - Don't unregister from the refresh driver unless we are also queueing events; r=dbaron (715c9caa1) - Bug 1154615 part 5 - Rename AnimationPlayerCollection to AnimationCollection; r=jwatt (4c596f089) - Bug 1154615 part 6 - Rename references to players within layout/; r=jwatt (42405f3fc) - Bug 1154615 part 7 - Rename CSSAnimationPlayer and CSSTransitionPlayer; r=jwatt (49ab272ed) - Bug 1154615 part 8 - Rename references to players in animation observers; r=jwatt (c3fa26d7a) - Bug 1154615 part 9 - Rename test files; r=jwatt (9d9f03e7b) - Bug 1145439 (Part 1) - Throttle requestAnimationFrame for non-visible iframes. r=mstange,mchang (be7d183d6) - Bug 1145439 (Part 2) - Make test_scroll_event_ordering.html wait for rAF to unthrottle. r=roc (9ac8317c9) - Bug 1144324 - Try to register for, and handle, touch events when APZ is enabled. r=dvander,jimm (fb75d1665) - Bug 1144324 - Remove the codepaths that conditionally enable touch events based on touch the presence of touch listeners. r=smaug,jimm (710617e6b) - Bug 1003991 - Disable https:// only load for ServiceWorkers when Developer Tools are open. r=nsm, r=miker (9d6669814) - Bug 1153267 - part 1 - use smart-pointer .forget() instead of NS_ADDREF+assign; r=ehsan (e4555c90c) - Bug 1153267 - part 2 - use smart pointers instead of manual NS_ADDREF'ing outparams; r=ehsan (ae8b60d5a) - Bug 1153267 - fix typo that broke OS X builds on a CLOSED TREE; r=bustage (08fdb3c4f) - Bug 1146843 - Revert part of cset 33c30e283fa8 because the code is used in Fennec. r=snorp (407248257) - Bug 1151940 part 1. Make some readonly properties defined on Window by CSSOM-view replaceable. r=smaug (5cb9b91f0) - Bug 1151940 part 2. Add a convenience function in nsGlobalWindow for replacing a property on the window with a new value. r=smaug (2ba39331c) - Bug 1151940 part 3. Make some writable cssom-view attributes that we only allow setting from chrome act the way readonly replaceables would when called from content. r=smaug (b485e1b44) - Goanna -> Gecko (2c539d7be) - Goanna -> Gecko (25d34e213) - Bug 1148962 - Use TakeOwnershipOfErrorReporting in CPOW code (r=bholley) (96c997639) - pointer style (a07fbffaa) - Bug 1152577: Add 'aReason' argument to AutoEntryScript constructor, and provide plausible names for its instantiations. r=bholley (512fa27e2) - bug 1155691 - Expose WindowRoot to chrome from window in webidl. r=smaug (235281924) - Bug 404828 - No need to assert that the top window isn't reachable. r=smaug (d73154fa0) - Bug 404828 - Followup: remove assertion expectations on a CLOSED TREE. a=tomcat (a5dabe1b7) - Bug 1156102 - Mark nsGlobalWindowObserver::mWindow as MOZ_NON_OWNING_REF; r=baku (c0d4208b7) - Bug 1107801 - Improve gamepad support on MacOS. r=ted (c591bd5ac) - Goanna -> Gecko (d9b81bc9e) - Bug 852944 - Gamepad API IPC; r=ted, r=baku (521892538) - Bug 1143529 part 1. Stop manually calling WrapObject in DataStoreService::GetDataStoresResolve. r=baku (056ad6bfe) - Bug 1143529 part 2. Tighten up the assert in binding Wrap methods. r=peterv (765a13325) - Bug 1152169 - DataStoreService should check if the first revision exists, r=bent (ee371cc5d) - Bug 1152169 followup: Mark FirstRevisionIdCallback methods Run() and HandleEvent() as 'override'. rs=ehsan (8186c4168) - Bug 1143651 - don't use CallQueryInterface when the compiler can do the cast for us; r=ehsan (a50f0a54b) - Bug 1144322 - Handle tabindex in overridden IsInteractiveHTMLContent methods. r=smaug (fd4b9beed) - Bug 1086684 - Stash the full path for file inputs to avoid doing IPC at inopportune times. r=ehsan/bent/gps (b843b1efc) - Bug 1143934 - Disallow mozSetFileNameArray in content processes. r=ehsan (42e5c8c6d) - Bug 1143934 - Fix assorted forms mochitests for e10s-compatibility. r=smaug (7a3babfed) - Bug 1143934 - Work around SessionStore dependency on current brokenness. r=ttaubert (5b0fcb5ce) - Bug 956530 - Clear the delayed caret data when clicking on a selected part of a text control if the focus event handler selects the control; r=roc (2859f07b4) - Bug 956530 follow-up: Fix the test failure on Windows 8 caused by the text box having a glowing outline as a result of being clicked on (d34e8da1a) - Bug 1157898 part 1. Make code of the form "return rv.ErrorCode();" where rv is an ErrorResult use StealNSResult instead. r=peterv (800da50e2) - Bug 1157898 part 2. Make code of the form "NS_ENSURE_SUCCESS(rv.ErrorCode(), rv.ErrorCode());" use Failed and StealNSResult instead. r=peterv (472432a83) - Bug 1157898 part 3. Fix the remaining consumers of rv.ErrorCode() in NS_ENSURE_* expressions to not do that. r=peterv (d452807e7) - Bug 1122238 part 1. Switch to using the new stackframe APIs in JSStackFrame. r=bholley (9d87b261a) - Bug 1122238 part 2. Stop caching things in JSStackFrame when we're called over Xrays. r=bholley (83eda7275) - Bug 1122238 part 3. Drop all the DOMException-cloning and sanitization gunk we added in bug 1107592 and bug 1107953 and bug 1117242 . r=bholley (f237aa948) - add support for NetBSD/SPARC64 (065783b70) - Bug 1153484 - Fetch should ignore invalid headers, but still process later headers. r=nsm (8925ddd77) - Bug 1157754 part 2. Convert consumers of ErrorResult::ClearMessage() to the new better APIs we have for suppressing exceptions on ErrorResult. r=bkelly (6519fbd5e) - Bug 1157754 part 3. Make ClearMessage private on ErrorResult. r=peterv (3fb218692) - Bug 1157898 part 4. Add ErrorResult::ErrorCodeIs() and use it in various places to get rid of ErrorCode(). r=peterv (bed7bfb4c) - Bug 1130686 - Refactor PromiseHolder in the service worker clients code. r=nsm (b3dbdcbfe) - Bug 1130686 - Implement client.focus. r=baku (5dee6d850) - Bug 1149163 part 1 - Clean up nsHTMLEditRules::GetInnerContent; r=froydnj (cc8f65b54) - Bug 1149163 part 2 - Make nsDOMIterator infallible; r=froydnj (d975f6c62) - Bug 1149163 part 3 - Clean up nsHTMLEditRules::BustUpInlinesAtBRs; r=froydnj (58155adad) - Bug 1149163 part 4 - Allow use of temporary nsBoolDomIterFunctor; r=froydnj (dbafec00f) - Bug 1149163 part 5 - Clean up nsHTMLEditRules::GetNodesForOperation; r=froydnj (41179d810) - Bug 1149163 part 6 - Clean up nsHTMLEditRules::LookInsideDivBQandList; r=froydnj (0b757bf14) - Bug 1149163 part 7 - Clean up nsHTMLEditRules::PromoteRange; r=froydnj (c49c714b1) - Bug 1149163 part 8 - Clean up nsHTMLEditRules::GetPromotedRanges; r=froydnj (5163a0026) - Bug 1148228 - Stop checking ul twice (43a22088c) - Bug 1141017 - resurrect serif and monospace. r=ehsan (95a1b6fcf) - Bug 1147412 part 1 - Make methods take nsINode*, not just nsIContent*; r=ehsan (7f762cdbe) - Bug 1147412 part 2 - Clean up nsHTMLEditor::SetInlinePropertyOnTextNode; r=ehsan (faf805587) - Bug 1147412 part 3 - Fix completely broken nsHTMLCSSUtils::IsCSSEquivalentToHTMLInlineStyleSet implementation; r=ehsan (73fea67c1) - Bug 1147412 part 4 - Clean up nsHTMLEditor::GetInlinePropertyBase; r=ehsan (3265bfbce) - Bug 1147412 part 5 - Clean up nsHTMLEditor::RemoveInlinePropertyImpl; r=ehsan (0f402bd7e) - Bug 1147412 part 6 - Remove nsHTMLCSSUtils::IsCSSEditableProperty(nsIDOMNode*,...); r=ehsan (100e4038a) - Bug 1147412 part 7 - Remove nsHTMLCSSUtils::GetComputedStyle(nsIDOMElement*); r=ehsan (6c51103bc) - Bug 1147412 part 8 - Clean up nsHTMLCSSUtils::IsCSSInvertible; r=ehsan (01e60c446) - Bug 1147412 part 9 - Convert some nsHTMLEditor members to Element; r=ehsan (e7efb1ac4) - Bug 1147412 part 10 - Clean up nsHTMLCSSUtils::Get*Property, GetCSSInlinePropertyBase; r=ehsan (54154143d) - Bug 1149163 part 9 - Clean up nsHTMLEditRules::GetNodesFromSelection; r=froydnj (5186308b9) - Bug 1154701 part 1 - Clean up nsHTMLEditor::CreateListOfNodesToPaste; r=ehsan (ea95238d5) - Bug 1153629 part 1 - Clean up nsHTMLEditRules::GetListActionNodes; r=ehsan (51f3b3e95) - Bug 1153629 part 2 - Clean up nsHTMLEditRules::GetParagraphFormatNodes; r=ehsan (a27bd7751) - Bug 1153629 part 3 - Clean up nsHTMLEditRules::GetNodesFromPoint; r=ehsan (edc7e4561) - Bug 1153629 part 4 - Clean up nsHTMLEditRules::ListIsEmptyLine; r=ehsan (ce3289bc7) - Bug 1153629 part 5 - Clean up nsHTMLEditRules::GetChildNodesForOperation; r=ehsan (b3a509dbf) - Bug 1153629 part 6 - Clean up nsHTMLEditRules::MakeBlockquote; r=ehsan (cb3808182) - Bug 1153629 part 7 - Clean up nsHTMLEditRules::RemoveBlockStyle, RemovePartOfBlock; r=ehsan (660b9f76e) - Bug 1153629 part 8 - Clean up nsHTMLEditRules::ApplyBlockStyle; r=ehsan (f54f9538c) - Bug 1153629 part 9 - Clean up nsHTMLEditRules::MakeTransitionList; r=ehsan (fb63cf6d8) - Bug 1153629 part 10 - Clean up nsHTMLEditRules::AlignInnerBlocks; r=ehsan (752d2df7a) - Bug 1153629 part 11 - Clean up nsHTMLEditRules::AdjustSpecialBreaks; r=ehsan (16ef0416b) - Bug 1153629 part 12 - Clean up nsHTMLEditRules::RemoveEmptyNodes; r=ehsan (d528e70e6) - Bug 1154701 part 2 - Use more OwningNonNull in editor; r=ehsan (85b1929e6) - Bug 1154701 part 3 - Clean up nsHTMLEditor::GetListAndTableParents, DiscoverPartialListsAndTables, ScanForListAndTableStructure, ReplaceOrphanedStructure; r=ehsan (7fe31f058) - Bug 1154701 part 4 - Switch nsHTMLEditor::mContentFilters to nsTArray; r=ehsan (64e6dd160) - Bug 1154701 part 5 - Switch nsHTMLEditor::objectResizeEventListeners to nsTArray; r=ehsan (036bc65fe) - Bug 1154701 part 6 - Clean up nsHTMLEditor::SetInlinePropertyOnNodeImpl; r=ehsan (2d619ca16) - Bug 1154701 part 7 - Clean up nsHTMLEditor::SetInlineProperty; r=ehsan (7a367d31b) - Bug 1154701 part 8 - Clean up nsHTMLEditor::SetInlinePropertyOnNode; r=ehsan (707c07d93) - Bug 1154701 part 9 - Clean up nsHTMLEditor::RelativeFontChange; r=ehsan (273ae9c64) - Bug 1154701 part 10 - Switch nsEditor::mActionListeners to nsTArray; r=ehsan (d2b5732fe) - Bug 1154701 part 11 - Switch nsEditor::mEditorObservers to nsTArray; r=ehsan (25a5af12e) - Bug 1154701 part 12 - Switch nsEditor::mDocStateListeners to nsTArray; r=ehsan (665af0792) - Bug 1154701 part 13 - Clean up nsHTMLEditor::SetCSSBackgroundColor; r=ehsan (ba424ade8) - Bug 1154701 part 14 - Remove unused nsCOMArray cruft; r=ehsan (3a8679a67) - Bug 1101651 - Part 1: xpcomrt version of dom media library need for standalone webrtcs. r=jesup (ae37b5464) - Bug 1137447 - New app update telemetry for patch type (complete or partial), extended error codes, and general cleanup. r=bbondy (c736ae502)
1120 lines
30 KiB
C++
1120 lines
30 KiB
C++
/* -*- 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/. */
|
|
|
|
/*
|
|
* Base class for DOM Core's nsIDOMComment, nsIDOMDocumentType, nsIDOMText,
|
|
* nsIDOMCDATASection, and nsIDOMProcessingInstruction nodes.
|
|
*/
|
|
|
|
#include "mozilla/DebugOnly.h"
|
|
|
|
#include "nsGenericDOMDataNode.h"
|
|
#include "mozilla/AsyncEventDispatcher.h"
|
|
#include "mozilla/MemoryReporting.h"
|
|
#include "mozilla/dom/Element.h"
|
|
#include "mozilla/dom/ShadowRoot.h"
|
|
#include "nsIDocument.h"
|
|
#include "nsIDOMDocument.h"
|
|
#include "nsReadableUtils.h"
|
|
#include "mozilla/InternalMutationEvent.h"
|
|
#include "nsIURI.h"
|
|
#include "nsIDOMEvent.h"
|
|
#include "nsIDOMText.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsDOMString.h"
|
|
#include "nsChangeHint.h"
|
|
#include "nsCOMArray.h"
|
|
#include "nsNodeUtils.h"
|
|
#include "mozilla/dom/DirectionalityUtils.h"
|
|
#include "nsBindingManager.h"
|
|
#include "nsCCUncollectableMarker.h"
|
|
#include "mozAutoDocUpdate.h"
|
|
|
|
#include "pldhash.h"
|
|
#include "prprf.h"
|
|
#include "nsWrapperCacheInlines.h"
|
|
|
|
using namespace mozilla;
|
|
using namespace mozilla::dom;
|
|
|
|
nsGenericDOMDataNode::nsGenericDOMDataNode(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
|
|
: nsIContent(aNodeInfo)
|
|
{
|
|
MOZ_ASSERT(mNodeInfo->NodeType() == nsIDOMNode::TEXT_NODE ||
|
|
mNodeInfo->NodeType() == nsIDOMNode::CDATA_SECTION_NODE ||
|
|
mNodeInfo->NodeType() == nsIDOMNode::COMMENT_NODE ||
|
|
mNodeInfo->NodeType() == nsIDOMNode::PROCESSING_INSTRUCTION_NODE ||
|
|
mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_TYPE_NODE,
|
|
"Bad NodeType in aNodeInfo");
|
|
}
|
|
|
|
nsGenericDOMDataNode::nsGenericDOMDataNode(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
|
|
: nsIContent(aNodeInfo)
|
|
{
|
|
MOZ_ASSERT(mNodeInfo->NodeType() == nsIDOMNode::TEXT_NODE ||
|
|
mNodeInfo->NodeType() == nsIDOMNode::CDATA_SECTION_NODE ||
|
|
mNodeInfo->NodeType() == nsIDOMNode::COMMENT_NODE ||
|
|
mNodeInfo->NodeType() == nsIDOMNode::PROCESSING_INSTRUCTION_NODE ||
|
|
mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_TYPE_NODE,
|
|
"Bad NodeType in aNodeInfo");
|
|
}
|
|
|
|
nsGenericDOMDataNode::~nsGenericDOMDataNode()
|
|
{
|
|
NS_PRECONDITION(!IsInDoc(),
|
|
"Please remove this from the document properly");
|
|
if (GetParent()) {
|
|
NS_RELEASE(mParent);
|
|
}
|
|
}
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(nsGenericDOMDataNode)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(nsGenericDOMDataNode)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsGenericDOMDataNode)
|
|
return Element::CanSkip(tmp, aRemovingAllowed);
|
|
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsGenericDOMDataNode)
|
|
return Element::CanSkipInCC(tmp);
|
|
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsGenericDOMDataNode)
|
|
return Element::CanSkipThis(tmp);
|
|
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGenericDOMDataNode)
|
|
if (MOZ_UNLIKELY(cb.WantDebugInfo())) {
|
|
char name[40];
|
|
PR_snprintf(name, sizeof(name), "nsGenericDOMDataNode (len=%d)",
|
|
tmp->mText.GetLength());
|
|
cb.DescribeRefCountedNode(tmp->mRefCnt.get(), name);
|
|
} else {
|
|
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsGenericDOMDataNode, tmp->mRefCnt.get())
|
|
}
|
|
|
|
// Always need to traverse script objects, so do that before we check
|
|
// if we're uncollectable.
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
|
|
|
if (!nsINode::Traverse(tmp, cb)) {
|
|
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
|
|
}
|
|
|
|
nsDataSlots *slots = tmp->GetExistingDataSlots();
|
|
if (slots) {
|
|
slots->Traverse(cb);
|
|
}
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGenericDOMDataNode)
|
|
nsINode::Unlink(tmp);
|
|
|
|
// Clear flag here because unlinking slots will clear the
|
|
// containing shadow root pointer.
|
|
tmp->UnsetFlags(NODE_IS_IN_SHADOW_TREE);
|
|
|
|
nsDataSlots *slots = tmp->GetExistingDataSlots();
|
|
if (slots) {
|
|
slots->Unlink();
|
|
}
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
|
|
NS_INTERFACE_MAP_BEGIN(nsGenericDOMDataNode)
|
|
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
|
NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsGenericDOMDataNode)
|
|
NS_INTERFACE_MAP_ENTRY(nsIContent)
|
|
NS_INTERFACE_MAP_ENTRY(nsINode)
|
|
NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
|
|
NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget)
|
|
NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISupportsWeakReference,
|
|
new nsNodeSupportsWeakRefTearoff(this))
|
|
// DOM bindings depend on the identity pointer being the
|
|
// same as nsINode (which nsIContent inherits).
|
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContent)
|
|
NS_INTERFACE_MAP_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsGenericDOMDataNode)
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE(nsGenericDOMDataNode,
|
|
nsNodeUtils::LastRelease(this))
|
|
|
|
|
|
void
|
|
nsGenericDOMDataNode::GetNodeValueInternal(nsAString& aNodeValue)
|
|
{
|
|
DebugOnly<nsresult> rv = GetData(aNodeValue);
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "GetData() failed!");
|
|
}
|
|
|
|
void
|
|
nsGenericDOMDataNode::SetNodeValueInternal(const nsAString& aNodeValue,
|
|
ErrorResult& aError)
|
|
{
|
|
aError = SetTextInternal(0, mText.GetLength(), aNodeValue.BeginReading(),
|
|
aNodeValue.Length(), true);
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Implementation of nsIDOMCharacterData
|
|
|
|
nsresult
|
|
nsGenericDOMDataNode::GetData(nsAString& aData) const
|
|
{
|
|
if (mText.Is2b()) {
|
|
aData.Assign(mText.Get2b(), mText.GetLength());
|
|
} else {
|
|
// Must use Substring() since nsDependentCString() requires null
|
|
// terminated strings.
|
|
|
|
const char *data = mText.Get1b();
|
|
|
|
if (data) {
|
|
CopyASCIItoUTF16(Substring(data, data + mText.GetLength()), aData);
|
|
} else {
|
|
aData.Truncate();
|
|
}
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsGenericDOMDataNode::SetData(const nsAString& aData)
|
|
{
|
|
return SetTextInternal(0, mText.GetLength(), aData.BeginReading(),
|
|
aData.Length(), true);
|
|
}
|
|
|
|
nsresult
|
|
nsGenericDOMDataNode::GetLength(uint32_t* aLength)
|
|
{
|
|
*aLength = mText.GetLength();
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsGenericDOMDataNode::SubstringData(uint32_t aStart, uint32_t aCount,
|
|
nsAString& aReturn)
|
|
{
|
|
ErrorResult rv;
|
|
SubstringData(aStart, aCount, aReturn, rv);
|
|
return rv.StealNSResult();
|
|
}
|
|
|
|
void
|
|
nsGenericDOMDataNode::SubstringData(uint32_t aStart, uint32_t aCount,
|
|
nsAString& aReturn, ErrorResult& rv)
|
|
{
|
|
aReturn.Truncate();
|
|
|
|
uint32_t textLength = mText.GetLength();
|
|
if (aStart > textLength) {
|
|
rv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
|
return;
|
|
}
|
|
|
|
uint32_t amount = aCount;
|
|
if (amount > textLength - aStart) {
|
|
amount = textLength - aStart;
|
|
}
|
|
|
|
if (mText.Is2b()) {
|
|
aReturn.Assign(mText.Get2b() + aStart, amount);
|
|
} else {
|
|
// Must use Substring() since nsDependentCString() requires null
|
|
// terminated strings.
|
|
|
|
const char *data = mText.Get1b() + aStart;
|
|
CopyASCIItoUTF16(Substring(data, data + amount), aReturn);
|
|
}
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsGenericDOMDataNode::MozRemove()
|
|
{
|
|
Remove();
|
|
return NS_OK;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
nsresult
|
|
nsGenericDOMDataNode::AppendData(const nsAString& aData)
|
|
{
|
|
return SetTextInternal(mText.GetLength(), 0, aData.BeginReading(),
|
|
aData.Length(), true);
|
|
}
|
|
|
|
nsresult
|
|
nsGenericDOMDataNode::InsertData(uint32_t aOffset,
|
|
const nsAString& aData)
|
|
{
|
|
return SetTextInternal(aOffset, 0, aData.BeginReading(),
|
|
aData.Length(), true);
|
|
}
|
|
|
|
nsresult
|
|
nsGenericDOMDataNode::DeleteData(uint32_t aOffset, uint32_t aCount)
|
|
{
|
|
return SetTextInternal(aOffset, aCount, nullptr, 0, true);
|
|
}
|
|
|
|
nsresult
|
|
nsGenericDOMDataNode::ReplaceData(uint32_t aOffset, uint32_t aCount,
|
|
const nsAString& aData)
|
|
{
|
|
return SetTextInternal(aOffset, aCount, aData.BeginReading(),
|
|
aData.Length(), true);
|
|
}
|
|
|
|
nsresult
|
|
nsGenericDOMDataNode::SetTextInternal(uint32_t aOffset, uint32_t aCount,
|
|
const char16_t* aBuffer,
|
|
uint32_t aLength, bool aNotify,
|
|
CharacterDataChangeInfo::Details* aDetails)
|
|
{
|
|
NS_PRECONDITION(aBuffer || !aLength,
|
|
"Null buffer passed to SetTextInternal!");
|
|
|
|
// sanitize arguments
|
|
uint32_t textLength = mText.GetLength();
|
|
if (aOffset > textLength) {
|
|
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
|
}
|
|
|
|
if (aCount > textLength - aOffset) {
|
|
aCount = textLength - aOffset;
|
|
}
|
|
|
|
uint32_t endOffset = aOffset + aCount;
|
|
|
|
// Make sure the text fragment can hold the new data.
|
|
if (aLength > aCount && !mText.CanGrowBy(aLength - aCount)) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
nsIDocument *document = GetComposedDoc();
|
|
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
|
|
|
|
bool haveMutationListeners = aNotify &&
|
|
nsContentUtils::HasMutationListeners(this,
|
|
NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED,
|
|
this);
|
|
|
|
nsCOMPtr<nsIAtom> oldValue;
|
|
if (haveMutationListeners) {
|
|
oldValue = GetCurrentValueAtom();
|
|
}
|
|
|
|
if (aNotify) {
|
|
CharacterDataChangeInfo info = {
|
|
aOffset == textLength,
|
|
aOffset,
|
|
endOffset,
|
|
aLength,
|
|
aDetails
|
|
};
|
|
nsNodeUtils::CharacterDataWillChange(this, &info);
|
|
}
|
|
|
|
Directionality oldDir = eDir_NotSet;
|
|
bool dirAffectsAncestor = (NodeType() == nsIDOMNode::TEXT_NODE &&
|
|
TextNodeWillChangeDirection(this, &oldDir, aOffset));
|
|
|
|
if (aOffset == 0 && endOffset == textLength) {
|
|
// Replacing whole text or old text was empty. Don't bother to check for
|
|
// bidi in this string if the document already has bidi enabled.
|
|
bool ok = mText.SetTo(aBuffer, aLength, !document || !document->GetBidiEnabled());
|
|
NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
|
|
}
|
|
else if (aOffset == textLength) {
|
|
// Appending to existing
|
|
bool ok = mText.Append(aBuffer, aLength, !document || !document->GetBidiEnabled());
|
|
NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
|
|
}
|
|
else {
|
|
// Merging old and new
|
|
|
|
// Allocate new buffer
|
|
int32_t newLength = textLength - aCount + aLength;
|
|
char16_t* to = new char16_t[newLength];
|
|
NS_ENSURE_TRUE(to, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
// Copy over appropriate data
|
|
if (aOffset) {
|
|
mText.CopyTo(to, 0, aOffset);
|
|
}
|
|
if (aLength) {
|
|
memcpy(to + aOffset, aBuffer, aLength * sizeof(char16_t));
|
|
}
|
|
if (endOffset != textLength) {
|
|
mText.CopyTo(to + aOffset + aLength, endOffset, textLength - endOffset);
|
|
}
|
|
|
|
bool ok = mText.SetTo(to, newLength, !document || !document->GetBidiEnabled());
|
|
|
|
delete [] to;
|
|
|
|
NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
|
|
}
|
|
|
|
UnsetFlags(NS_CACHED_TEXT_IS_ONLY_WHITESPACE);
|
|
|
|
if (document && mText.IsBidi()) {
|
|
// If we found bidi characters in mText.SetTo() above, indicate that the
|
|
// document contains bidi characters.
|
|
document->SetBidiEnabled();
|
|
}
|
|
|
|
if (dirAffectsAncestor) {
|
|
TextNodeChangedDirection(this, oldDir, aNotify);
|
|
}
|
|
|
|
// Notify observers
|
|
if (aNotify) {
|
|
CharacterDataChangeInfo info = {
|
|
aOffset == textLength,
|
|
aOffset,
|
|
endOffset,
|
|
aLength,
|
|
aDetails
|
|
};
|
|
nsNodeUtils::CharacterDataChanged(this, &info);
|
|
|
|
if (haveMutationListeners) {
|
|
InternalMutationEvent mutation(true, NS_MUTATION_CHARACTERDATAMODIFIED);
|
|
|
|
mutation.mPrevAttrValue = oldValue;
|
|
if (aLength > 0) {
|
|
nsAutoString val;
|
|
mText.AppendTo(val);
|
|
mutation.mNewAttrValue = do_GetAtom(val);
|
|
}
|
|
|
|
mozAutoSubtreeModified subtree(OwnerDoc(), this);
|
|
(new AsyncEventDispatcher(this, mutation))->RunDOMEventWhenSafe();
|
|
}
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Implementation of nsIContent
|
|
|
|
#ifdef DEBUG
|
|
void
|
|
nsGenericDOMDataNode::ToCString(nsAString& aBuf, int32_t aOffset,
|
|
int32_t aLen) const
|
|
{
|
|
if (mText.Is2b()) {
|
|
const char16_t* cp = mText.Get2b() + aOffset;
|
|
const char16_t* end = cp + aLen;
|
|
|
|
while (cp < end) {
|
|
char16_t ch = *cp++;
|
|
if (ch == '&') {
|
|
aBuf.AppendLiteral("&");
|
|
} else if (ch == '<') {
|
|
aBuf.AppendLiteral("<");
|
|
} else if (ch == '>') {
|
|
aBuf.AppendLiteral(">");
|
|
} else if ((ch < ' ') || (ch >= 127)) {
|
|
char buf[10];
|
|
PR_snprintf(buf, sizeof(buf), "\\u%04x", ch);
|
|
AppendASCIItoUTF16(buf, aBuf);
|
|
} else {
|
|
aBuf.Append(ch);
|
|
}
|
|
}
|
|
} else {
|
|
unsigned char* cp = (unsigned char*)mText.Get1b() + aOffset;
|
|
const unsigned char* end = cp + aLen;
|
|
|
|
while (cp < end) {
|
|
char16_t ch = *cp++;
|
|
if (ch == '&') {
|
|
aBuf.AppendLiteral("&");
|
|
} else if (ch == '<') {
|
|
aBuf.AppendLiteral("<");
|
|
} else if (ch == '>') {
|
|
aBuf.AppendLiteral(">");
|
|
} else if ((ch < ' ') || (ch >= 127)) {
|
|
char buf[10];
|
|
PR_snprintf(buf, sizeof(buf), "\\u%04x", ch);
|
|
AppendASCIItoUTF16(buf, aBuf);
|
|
} else {
|
|
aBuf.Append(ch);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
nsresult
|
|
nsGenericDOMDataNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
|
nsIContent* aBindingParent,
|
|
bool aCompileEventHandlers)
|
|
{
|
|
NS_PRECONDITION(aParent || aDocument, "Must have document if no parent!");
|
|
NS_PRECONDITION(NODE_FROM(aParent, aDocument)->OwnerDoc() == OwnerDoc(),
|
|
"Must have the same owner document");
|
|
NS_PRECONDITION(!aParent || aDocument == aParent->GetUncomposedDoc(),
|
|
"aDocument must be current doc of aParent");
|
|
NS_PRECONDITION(!GetUncomposedDoc() && !IsInDoc(),
|
|
"Already have a document. Unbind first!");
|
|
// Note that as we recurse into the kids, they'll have a non-null parent. So
|
|
// only assert if our parent is _changing_ while we have a parent.
|
|
NS_PRECONDITION(!GetParent() || aParent == GetParent(),
|
|
"Already have a parent. Unbind first!");
|
|
NS_PRECONDITION(!GetBindingParent() ||
|
|
aBindingParent == GetBindingParent() ||
|
|
(!aBindingParent && aParent &&
|
|
aParent->GetBindingParent() == GetBindingParent()),
|
|
"Already have a binding parent. Unbind first!");
|
|
NS_PRECONDITION(aBindingParent != this,
|
|
"Content must not be its own binding parent");
|
|
NS_PRECONDITION(!IsRootOfNativeAnonymousSubtree() ||
|
|
aBindingParent == aParent,
|
|
"Native anonymous content must have its parent as its "
|
|
"own binding parent");
|
|
|
|
if (!aBindingParent && aParent) {
|
|
aBindingParent = aParent->GetBindingParent();
|
|
}
|
|
|
|
// First set the binding parent
|
|
if (aBindingParent) {
|
|
NS_ASSERTION(IsRootOfNativeAnonymousSubtree() ||
|
|
!HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE) ||
|
|
(aParent && aParent->IsInNativeAnonymousSubtree()),
|
|
"Trying to re-bind content from native anonymous subtree to "
|
|
"non-native anonymous parent!");
|
|
DataSlots()->mBindingParent = aBindingParent; // Weak, so no addref happens.
|
|
if (aParent->IsInNativeAnonymousSubtree()) {
|
|
SetFlags(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE);
|
|
}
|
|
if (aParent->HasFlag(NODE_CHROME_ONLY_ACCESS)) {
|
|
SetFlags(NODE_CHROME_ONLY_ACCESS);
|
|
}
|
|
if (aParent->IsInShadowTree()) {
|
|
ClearSubtreeRootPointer();
|
|
SetFlags(NODE_IS_IN_SHADOW_TREE);
|
|
}
|
|
ShadowRoot* parentContainingShadow = aParent->GetContainingShadow();
|
|
if (parentContainingShadow) {
|
|
DataSlots()->mContainingShadow = parentContainingShadow;
|
|
}
|
|
}
|
|
|
|
// Set parent
|
|
if (aParent) {
|
|
if (!GetParent()) {
|
|
NS_ADDREF(aParent);
|
|
}
|
|
mParent = aParent;
|
|
}
|
|
else {
|
|
mParent = aDocument;
|
|
}
|
|
SetParentIsContent(aParent);
|
|
|
|
// XXXbz sXBL/XBL2 issue!
|
|
|
|
// Set document
|
|
if (aDocument) {
|
|
// We no longer need to track the subtree pointer (and in fact we'll assert
|
|
// if we do this any later).
|
|
ClearSubtreeRootPointer();
|
|
|
|
// XXX See the comment in Element::BindToTree
|
|
SetInDocument();
|
|
if (mText.IsBidi()) {
|
|
aDocument->SetBidiEnabled();
|
|
}
|
|
// Clear the lazy frame construction bits.
|
|
UnsetFlags(NODE_NEEDS_FRAME | NODE_DESCENDANTS_NEED_FRAMES);
|
|
} else if (!IsInShadowTree()) {
|
|
// If we're not in the doc and not in a shadow tree,
|
|
// update our subtree pointer.
|
|
SetSubtreeRootPointer(aParent->SubtreeRoot());
|
|
}
|
|
|
|
nsNodeUtils::ParentChainChanged(this);
|
|
|
|
UpdateEditableState(false);
|
|
|
|
NS_POSTCONDITION(aDocument == GetUncomposedDoc(), "Bound to wrong document");
|
|
NS_POSTCONDITION(aParent == GetParent(), "Bound to wrong parent");
|
|
NS_POSTCONDITION(aBindingParent == GetBindingParent(),
|
|
"Bound to wrong binding parent");
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
void
|
|
nsGenericDOMDataNode::UnbindFromTree(bool aDeep, bool aNullParent)
|
|
{
|
|
// Unset frame flags; if we need them again later, they'll get set again.
|
|
UnsetFlags(NS_CREATE_FRAME_IF_NON_WHITESPACE |
|
|
NS_REFRAME_IF_WHITESPACE);
|
|
|
|
nsIDocument* document =
|
|
HasFlag(NODE_FORCE_XBL_BINDINGS) ? OwnerDoc() : GetComposedDoc();
|
|
|
|
if (aNullParent) {
|
|
if (GetParent()) {
|
|
NS_RELEASE(mParent);
|
|
} else {
|
|
mParent = nullptr;
|
|
}
|
|
SetParentIsContent(false);
|
|
}
|
|
ClearInDocument();
|
|
|
|
if (aNullParent || !mParent->IsInShadowTree()) {
|
|
UnsetFlags(NODE_IS_IN_SHADOW_TREE);
|
|
|
|
// Begin keeping track of our subtree root.
|
|
SetSubtreeRootPointer(aNullParent ? this : mParent->SubtreeRoot());
|
|
}
|
|
|
|
if (document && !GetContainingShadow()) {
|
|
// Notify XBL- & nsIAnonymousContentCreator-generated
|
|
// anonymous content that the document is changing.
|
|
// Unlike XBL, bindings for web components shadow DOM
|
|
// do not get uninstalled.
|
|
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
|
|
nsContentUtils::AddScriptRunner(
|
|
new RemoveFromBindingManagerRunnable(document->BindingManager(), this,
|
|
document));
|
|
}
|
|
}
|
|
|
|
nsDataSlots *slots = GetExistingDataSlots();
|
|
if (slots) {
|
|
slots->mBindingParent = nullptr;
|
|
if (aNullParent || !mParent->IsInShadowTree()) {
|
|
slots->mContainingShadow = nullptr;
|
|
}
|
|
}
|
|
|
|
nsNodeUtils::ParentChainChanged(this);
|
|
}
|
|
|
|
already_AddRefed<nsINodeList>
|
|
nsGenericDOMDataNode::GetChildren(uint32_t aFilter)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
nsresult
|
|
nsGenericDOMDataNode::SetAttr(int32_t aNameSpaceID, nsIAtom* aAttr,
|
|
nsIAtom* aPrefix, const nsAString& aValue,
|
|
bool aNotify)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsGenericDOMDataNode::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttr,
|
|
bool aNotify)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
const nsAttrName*
|
|
nsGenericDOMDataNode::GetAttrNameAt(uint32_t aIndex) const
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
uint32_t
|
|
nsGenericDOMDataNode::GetAttrCount() const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
uint32_t
|
|
nsGenericDOMDataNode::GetChildCount() const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
nsIContent *
|
|
nsGenericDOMDataNode::GetChildAt(uint32_t aIndex) const
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
nsIContent * const *
|
|
nsGenericDOMDataNode::GetChildArray(uint32_t* aChildCount) const
|
|
{
|
|
*aChildCount = 0;
|
|
return nullptr;
|
|
}
|
|
|
|
int32_t
|
|
nsGenericDOMDataNode::IndexOf(const nsINode* aPossibleChild) const
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
nsresult
|
|
nsGenericDOMDataNode::InsertChildAt(nsIContent* aKid, uint32_t aIndex,
|
|
bool aNotify)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
void
|
|
nsGenericDOMDataNode::RemoveChildAt(uint32_t aIndex, bool aNotify)
|
|
{
|
|
}
|
|
|
|
nsIContent *
|
|
nsGenericDOMDataNode::GetBindingParent() const
|
|
{
|
|
nsDataSlots *slots = GetExistingDataSlots();
|
|
return slots ? slots->mBindingParent : nullptr;
|
|
}
|
|
|
|
ShadowRoot *
|
|
nsGenericDOMDataNode::GetShadowRoot() const
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
ShadowRoot *
|
|
nsGenericDOMDataNode::GetContainingShadow() const
|
|
{
|
|
nsDataSlots *slots = GetExistingDataSlots();
|
|
return slots ? slots->mContainingShadow : nullptr;
|
|
}
|
|
|
|
void
|
|
nsGenericDOMDataNode::SetShadowRoot(ShadowRoot* aShadowRoot)
|
|
{
|
|
}
|
|
|
|
nsTArray<nsIContent*>&
|
|
nsGenericDOMDataNode::DestInsertionPoints()
|
|
{
|
|
nsDataSlots *slots = DataSlots();
|
|
return slots->mDestInsertionPoints;
|
|
}
|
|
|
|
nsTArray<nsIContent*>*
|
|
nsGenericDOMDataNode::GetExistingDestInsertionPoints() const
|
|
{
|
|
nsDataSlots *slots = GetExistingDataSlots();
|
|
if (slots) {
|
|
return &slots->mDestInsertionPoints;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
nsXBLBinding *
|
|
nsGenericDOMDataNode::GetXBLBinding() const
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
void
|
|
nsGenericDOMDataNode::SetXBLBinding(nsXBLBinding* aBinding,
|
|
nsBindingManager* aOldBindingManager)
|
|
{
|
|
}
|
|
|
|
nsIContent *
|
|
nsGenericDOMDataNode::GetXBLInsertionParent() const
|
|
{
|
|
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
|
|
nsDataSlots *slots = GetExistingDataSlots();
|
|
if (slots) {
|
|
return slots->mXBLInsertionParent;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void
|
|
nsGenericDOMDataNode::SetXBLInsertionParent(nsIContent* aContent)
|
|
{
|
|
if (aContent) {
|
|
nsDataSlots *slots = DataSlots();
|
|
SetFlags(NODE_MAY_BE_IN_BINDING_MNGR);
|
|
slots->mXBLInsertionParent = aContent;
|
|
} else {
|
|
nsDataSlots *slots = GetExistingDataSlots();
|
|
if (slots) {
|
|
slots->mXBLInsertionParent = nullptr;
|
|
}
|
|
}
|
|
}
|
|
|
|
CustomElementData *
|
|
nsGenericDOMDataNode::GetCustomElementData() const
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
void
|
|
nsGenericDOMDataNode::SetCustomElementData(CustomElementData* aData)
|
|
{
|
|
}
|
|
|
|
bool
|
|
nsGenericDOMDataNode::IsNodeOfType(uint32_t aFlags) const
|
|
{
|
|
return !(aFlags & ~(eCONTENT | eDATA_NODE));
|
|
}
|
|
|
|
void
|
|
nsGenericDOMDataNode::SaveSubtreeState()
|
|
{
|
|
}
|
|
|
|
void
|
|
nsGenericDOMDataNode::DestroyContent()
|
|
{
|
|
// XXX We really should let cycle collection do this, but that currently still
|
|
// leaks (see https://bugzilla.mozilla.org/show_bug.cgi?id=406684).
|
|
ReleaseWrapper(this);
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
void
|
|
nsGenericDOMDataNode::List(FILE* out, int32_t aIndent) const
|
|
{
|
|
}
|
|
|
|
void
|
|
nsGenericDOMDataNode::DumpContent(FILE* out, int32_t aIndent,
|
|
bool aDumpAll) const
|
|
{
|
|
}
|
|
#endif
|
|
|
|
bool
|
|
nsGenericDOMDataNode::IsLink(nsIURI** aURI) const
|
|
{
|
|
*aURI = nullptr;
|
|
return false;
|
|
}
|
|
|
|
nsINode::nsSlots*
|
|
nsGenericDOMDataNode::CreateSlots()
|
|
{
|
|
return new nsDataSlots();
|
|
}
|
|
|
|
nsGenericDOMDataNode::nsDataSlots::nsDataSlots()
|
|
: nsINode::nsSlots(), mBindingParent(nullptr)
|
|
{
|
|
}
|
|
|
|
void
|
|
nsGenericDOMDataNode::nsDataSlots::Traverse(nsCycleCollectionTraversalCallback &cb)
|
|
{
|
|
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mXBLInsertionParent");
|
|
cb.NoteXPCOMChild(mXBLInsertionParent.get());
|
|
|
|
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mContainingShadow");
|
|
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mContainingShadow));
|
|
}
|
|
|
|
void
|
|
nsGenericDOMDataNode::nsDataSlots::Unlink()
|
|
{
|
|
mXBLInsertionParent = nullptr;
|
|
mContainingShadow = nullptr;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Implementation of the nsIDOMText interface
|
|
|
|
nsresult
|
|
nsGenericDOMDataNode::SplitData(uint32_t aOffset, nsIContent** aReturn,
|
|
bool aCloneAfterOriginal)
|
|
{
|
|
*aReturn = nullptr;
|
|
nsresult rv = NS_OK;
|
|
nsAutoString cutText;
|
|
uint32_t length = TextLength();
|
|
|
|
if (aOffset > length) {
|
|
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
|
}
|
|
|
|
uint32_t cutStartOffset = aCloneAfterOriginal ? aOffset : 0;
|
|
uint32_t cutLength = aCloneAfterOriginal ? length - aOffset : aOffset;
|
|
rv = SubstringData(cutStartOffset, cutLength, cutText);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
nsIDocument* document = GetComposedDoc();
|
|
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, true);
|
|
|
|
// Use Clone for creating the new node so that the new node is of same class
|
|
// as this node!
|
|
nsCOMPtr<nsIContent> newContent = CloneDataNode(mNodeInfo, false);
|
|
if (!newContent) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
newContent->SetText(cutText, true); // XXX should be false?
|
|
|
|
CharacterDataChangeInfo::Details details = {
|
|
CharacterDataChangeInfo::Details::eSplit, newContent
|
|
};
|
|
rv = SetTextInternal(cutStartOffset, cutLength, nullptr, 0, true,
|
|
aCloneAfterOriginal ? &details : nullptr);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
nsCOMPtr<nsINode> parent = GetParentNode();
|
|
if (parent) {
|
|
int32_t insertionIndex = parent->IndexOf(this);
|
|
if (aCloneAfterOriginal) {
|
|
++insertionIndex;
|
|
}
|
|
parent->InsertChildAt(newContent, insertionIndex, true);
|
|
}
|
|
|
|
newContent.swap(*aReturn);
|
|
return rv;
|
|
}
|
|
|
|
nsresult
|
|
nsGenericDOMDataNode::SplitText(uint32_t aOffset, nsIDOMText** aReturn)
|
|
{
|
|
nsCOMPtr<nsIContent> newChild;
|
|
nsresult rv = SplitData(aOffset, getter_AddRefs(newChild));
|
|
if (NS_SUCCEEDED(rv)) {
|
|
rv = CallQueryInterface(newChild, aReturn);
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
/* static */ int32_t
|
|
nsGenericDOMDataNode::FirstLogicallyAdjacentTextNode(nsIContent* aParent,
|
|
int32_t aIndex)
|
|
{
|
|
while (aIndex-- > 0) {
|
|
nsIContent* sibling = aParent->GetChildAt(aIndex);
|
|
if (!sibling->IsNodeOfType(nsINode::eTEXT))
|
|
return aIndex + 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* static */ int32_t
|
|
nsGenericDOMDataNode::LastLogicallyAdjacentTextNode(nsIContent* aParent,
|
|
int32_t aIndex,
|
|
uint32_t aCount)
|
|
{
|
|
while (++aIndex < int32_t(aCount)) {
|
|
nsIContent* sibling = aParent->GetChildAt(aIndex);
|
|
if (!sibling->IsNodeOfType(nsINode::eTEXT))
|
|
return aIndex - 1;
|
|
}
|
|
return aCount - 1;
|
|
}
|
|
|
|
nsresult
|
|
nsGenericDOMDataNode::GetWholeText(nsAString& aWholeText)
|
|
{
|
|
nsIContent* parent = GetParent();
|
|
|
|
// Handle parent-less nodes
|
|
if (!parent)
|
|
return GetData(aWholeText);
|
|
|
|
int32_t index = parent->IndexOf(this);
|
|
NS_WARN_IF_FALSE(index >= 0,
|
|
"Trying to use .wholeText with an anonymous"
|
|
"text node child of a binding parent?");
|
|
NS_ENSURE_TRUE(index >= 0, NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
|
int32_t first =
|
|
FirstLogicallyAdjacentTextNode(parent, index);
|
|
int32_t last =
|
|
LastLogicallyAdjacentTextNode(parent, index, parent->GetChildCount());
|
|
|
|
aWholeText.Truncate();
|
|
|
|
nsCOMPtr<nsIDOMText> node;
|
|
nsAutoString tmp;
|
|
do {
|
|
node = do_QueryInterface(parent->GetChildAt(first));
|
|
node->GetData(tmp);
|
|
aWholeText.Append(tmp);
|
|
} while (first++ < last);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Implementation of the nsIContent interface text functions
|
|
|
|
const nsTextFragment *
|
|
nsGenericDOMDataNode::GetText()
|
|
{
|
|
return &mText;
|
|
}
|
|
|
|
uint32_t
|
|
nsGenericDOMDataNode::TextLength() const
|
|
{
|
|
return mText.GetLength();
|
|
}
|
|
|
|
nsresult
|
|
nsGenericDOMDataNode::SetText(const char16_t* aBuffer,
|
|
uint32_t aLength,
|
|
bool aNotify)
|
|
{
|
|
return SetTextInternal(0, mText.GetLength(), aBuffer, aLength, aNotify);
|
|
}
|
|
|
|
nsresult
|
|
nsGenericDOMDataNode::AppendText(const char16_t* aBuffer,
|
|
uint32_t aLength,
|
|
bool aNotify)
|
|
{
|
|
return SetTextInternal(mText.GetLength(), 0, aBuffer, aLength, aNotify);
|
|
}
|
|
|
|
bool
|
|
nsGenericDOMDataNode::TextIsOnlyWhitespace()
|
|
{
|
|
// FIXME: should this method take content language into account?
|
|
if (mText.Is2b()) {
|
|
// The fragment contains non-8bit characters and such characters
|
|
// are never considered whitespace.
|
|
return false;
|
|
}
|
|
|
|
if (HasFlag(NS_CACHED_TEXT_IS_ONLY_WHITESPACE)) {
|
|
return HasFlag(NS_TEXT_IS_ONLY_WHITESPACE);
|
|
}
|
|
|
|
const char* cp = mText.Get1b();
|
|
const char* end = cp + mText.GetLength();
|
|
|
|
while (cp < end) {
|
|
char ch = *cp;
|
|
|
|
if (!dom::IsSpaceCharacter(ch)) {
|
|
UnsetFlags(NS_TEXT_IS_ONLY_WHITESPACE);
|
|
SetFlags(NS_CACHED_TEXT_IS_ONLY_WHITESPACE);
|
|
return false;
|
|
}
|
|
|
|
++cp;
|
|
}
|
|
|
|
SetFlags(NS_CACHED_TEXT_IS_ONLY_WHITESPACE | NS_TEXT_IS_ONLY_WHITESPACE);
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
nsGenericDOMDataNode::HasTextForTranslation()
|
|
{
|
|
if (NodeType() != nsIDOMNode::TEXT_NODE &&
|
|
NodeType() != nsIDOMNode::CDATA_SECTION_NODE) {
|
|
return false;
|
|
}
|
|
|
|
if (mText.Is2b()) {
|
|
// The fragment contains non-8bit characters which means there
|
|
// was at least one "interesting" character to trigger non-8bit.
|
|
return true;
|
|
}
|
|
|
|
if (HasFlag(NS_CACHED_TEXT_IS_ONLY_WHITESPACE) &&
|
|
HasFlag(NS_TEXT_IS_ONLY_WHITESPACE)) {
|
|
return false;
|
|
}
|
|
|
|
const char* cp = mText.Get1b();
|
|
const char* end = cp + mText.GetLength();
|
|
|
|
unsigned char ch;
|
|
for (; cp < end; cp++) {
|
|
ch = *cp;
|
|
|
|
// These are the characters that are letters
|
|
// in the first 256 UTF-8 codepoints.
|
|
if ((ch >= 'a' && ch <= 'z') ||
|
|
(ch >= 'A' && ch <= 'Z') ||
|
|
(ch >= 192 && ch <= 214) ||
|
|
(ch >= 216 && ch <= 246) ||
|
|
(ch >= 248)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void
|
|
nsGenericDOMDataNode::AppendTextTo(nsAString& aResult)
|
|
{
|
|
mText.AppendTo(aResult);
|
|
}
|
|
|
|
bool
|
|
nsGenericDOMDataNode::AppendTextTo(nsAString& aResult,
|
|
const mozilla::fallible_t& aFallible)
|
|
{
|
|
return mText.AppendTo(aResult, aFallible);
|
|
}
|
|
|
|
already_AddRefed<nsIAtom>
|
|
nsGenericDOMDataNode::GetCurrentValueAtom()
|
|
{
|
|
nsAutoString val;
|
|
GetData(val);
|
|
return NS_NewAtom(val);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsGenericDOMDataNode::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP_(bool)
|
|
nsGenericDOMDataNode::IsAttributeMapped(const nsIAtom* aAttribute) const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
nsChangeHint
|
|
nsGenericDOMDataNode::GetAttributeChangeHint(const nsIAtom* aAttribute,
|
|
int32_t aModType) const
|
|
{
|
|
NS_NOTREACHED("Shouldn't be calling this!");
|
|
return nsChangeHint(0);
|
|
}
|
|
|
|
size_t
|
|
nsGenericDOMDataNode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
|
{
|
|
size_t n = nsIContent::SizeOfExcludingThis(aMallocSizeOf);
|
|
n += mText.SizeOfExcludingThis(aMallocSizeOf);
|
|
return n;
|
|
}
|
|
|