mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +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)
594 lines
16 KiB
C++
594 lines
16 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* 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/. */
|
|
|
|
/*
|
|
* Implementation of the |attributes| property of DOM Core's Element object.
|
|
*/
|
|
|
|
#include "nsDOMAttributeMap.h"
|
|
|
|
#include "mozilla/MemoryReporting.h"
|
|
#include "mozilla/dom/Attr.h"
|
|
#include "mozilla/dom/Element.h"
|
|
#include "mozilla/dom/NamedNodeMapBinding.h"
|
|
#include "mozilla/dom/NodeInfoInlines.h"
|
|
#include "nsAttrName.h"
|
|
#include "nsContentUtils.h"
|
|
#include "nsError.h"
|
|
#include "nsIContentInlines.h"
|
|
#include "nsIDocument.h"
|
|
#include "nsNameSpaceManager.h"
|
|
#include "nsNodeInfoManager.h"
|
|
#include "nsUnicharUtils.h"
|
|
#include "nsWrapperCacheInlines.h"
|
|
|
|
using namespace mozilla;
|
|
using namespace mozilla::dom;
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
nsDOMAttributeMap::nsDOMAttributeMap(Element* aContent)
|
|
: mContent(aContent)
|
|
{
|
|
// We don't add a reference to our content. If it goes away,
|
|
// we'll be told to drop our reference
|
|
}
|
|
|
|
/**
|
|
* Clear map pointer for attributes.
|
|
*/
|
|
PLDHashOperator
|
|
RemoveMapRef(nsAttrHashKey::KeyType aKey, nsRefPtr<Attr>& aData,
|
|
void* aUserArg)
|
|
{
|
|
aData->SetMap(nullptr);
|
|
|
|
return PL_DHASH_REMOVE;
|
|
}
|
|
|
|
nsDOMAttributeMap::~nsDOMAttributeMap()
|
|
{
|
|
if (mAttributeCache) {
|
|
mAttributeCache->Enumerate(RemoveMapRef, nullptr);
|
|
}
|
|
}
|
|
|
|
void
|
|
nsDOMAttributeMap::DropReference()
|
|
{
|
|
if (mAttributeCache) {
|
|
mAttributeCache->Enumerate(RemoveMapRef, nullptr);
|
|
}
|
|
mContent = nullptr;
|
|
}
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMAttributeMap)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMAttributeMap)
|
|
tmp->DropReference();
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mContent)
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
|
|
|
|
PLDHashOperator
|
|
TraverseMapEntry(nsAttrHashKey::KeyType aKey, nsRefPtr<Attr>& aData,
|
|
void* aUserArg)
|
|
{
|
|
nsCycleCollectionTraversalCallback *cb =
|
|
static_cast<nsCycleCollectionTraversalCallback*>(aUserArg);
|
|
|
|
cb->NoteXPCOMChild(static_cast<nsINode*>(aData.get()));
|
|
|
|
return PL_DHASH_NEXT;
|
|
}
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMAttributeMap)
|
|
if (tmp->mAttributeCache) {
|
|
tmp->mAttributeCache->Enumerate(TraverseMapEntry, &cb);
|
|
}
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContent)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(nsDOMAttributeMap)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsDOMAttributeMap)
|
|
if (tmp->IsBlack()) {
|
|
if (tmp->mContent) {
|
|
// The map owns the element so we can mark it when the
|
|
// map itself is certainly alive.
|
|
mozilla::dom::FragmentOrElement::MarkNodeChildren(tmp->mContent);
|
|
}
|
|
return true;
|
|
}
|
|
if (tmp->mContent &&
|
|
mozilla::dom::FragmentOrElement::CanSkip(tmp->mContent, true)) {
|
|
return true;
|
|
}
|
|
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsDOMAttributeMap)
|
|
return tmp->IsBlackAndDoesNotNeedTracing(tmp);
|
|
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsDOMAttributeMap)
|
|
return tmp->IsBlack();
|
|
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
|
|
|
|
// QueryInterface implementation for nsDOMAttributeMap
|
|
NS_INTERFACE_TABLE_HEAD(nsDOMAttributeMap)
|
|
NS_INTERFACE_TABLE(nsDOMAttributeMap, nsIDOMMozNamedAttrMap)
|
|
NS_INTERFACE_TABLE_TO_MAP_SEGUE
|
|
NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY
|
|
NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsDOMAttributeMap)
|
|
NS_INTERFACE_MAP_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMAttributeMap)
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMAttributeMap)
|
|
|
|
PLDHashOperator
|
|
SetOwnerDocumentFunc(nsAttrHashKey::KeyType aKey,
|
|
nsRefPtr<Attr>& aData,
|
|
void* aUserArg)
|
|
{
|
|
nsresult rv = aData->SetOwnerDocument(static_cast<nsIDocument*>(aUserArg));
|
|
|
|
return NS_FAILED(rv) ? PL_DHASH_STOP : PL_DHASH_NEXT;
|
|
}
|
|
|
|
nsresult
|
|
nsDOMAttributeMap::SetOwnerDocument(nsIDocument* aDocument)
|
|
{
|
|
if (mAttributeCache) {
|
|
uint32_t n = mAttributeCache->Enumerate(SetOwnerDocumentFunc, aDocument);
|
|
NS_ENSURE_TRUE(n == mAttributeCache->Count(), NS_ERROR_FAILURE);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
void
|
|
nsDOMAttributeMap::DropAttribute(int32_t aNamespaceID, nsIAtom* aLocalName)
|
|
{
|
|
nsAttrKey attr(aNamespaceID, aLocalName);
|
|
if (mAttributeCache) {
|
|
Attr *node = mAttributeCache->GetWeak(attr);
|
|
if (node) {
|
|
// Break link to map
|
|
node->SetMap(nullptr);
|
|
|
|
// Remove from cache
|
|
mAttributeCache->Remove(attr);
|
|
}
|
|
}
|
|
}
|
|
|
|
already_AddRefed<Attr>
|
|
nsDOMAttributeMap::RemoveAttribute(mozilla::dom::NodeInfo* aNodeInfo)
|
|
{
|
|
NS_ASSERTION(aNodeInfo, "RemoveAttribute() called with aNodeInfo == nullptr!");
|
|
|
|
nsAttrKey attr(aNodeInfo->NamespaceID(), aNodeInfo->NameAtom());
|
|
|
|
nsRefPtr<Attr> node;
|
|
if (mAttributeCache && mAttributeCache->Get(attr, getter_AddRefs(node))) {
|
|
// Break link to map
|
|
node->SetMap(nullptr);
|
|
|
|
// Remove from cache
|
|
mAttributeCache->Remove(attr);
|
|
} else {
|
|
nsAutoString value;
|
|
// As we are removing the attribute we need to set the current value in
|
|
// the attribute node.
|
|
mContent->GetAttr(aNodeInfo->NamespaceID(), aNodeInfo->NameAtom(), value);
|
|
nsRefPtr<mozilla::dom::NodeInfo> ni = aNodeInfo;
|
|
node = new Attr(nullptr, ni.forget(), value, true);
|
|
}
|
|
|
|
return node.forget();
|
|
}
|
|
|
|
Attr*
|
|
nsDOMAttributeMap::GetAttribute(mozilla::dom::NodeInfo* aNodeInfo, bool aNsAware)
|
|
{
|
|
NS_ASSERTION(aNodeInfo, "GetAttribute() called with aNodeInfo == nullptr!");
|
|
|
|
nsAttrKey attr(aNodeInfo->NamespaceID(), aNodeInfo->NameAtom());
|
|
|
|
EnsureAttributeCache();
|
|
Attr* node = mAttributeCache->GetWeak(attr);
|
|
if (!node) {
|
|
nsRefPtr<mozilla::dom::NodeInfo> ni = aNodeInfo;
|
|
nsRefPtr<Attr> newAttr =
|
|
new Attr(this, ni.forget(), EmptyString(), aNsAware);
|
|
mAttributeCache->Put(attr, newAttr);
|
|
node = newAttr;
|
|
}
|
|
|
|
return node;
|
|
}
|
|
|
|
Attr*
|
|
nsDOMAttributeMap::NamedGetter(const nsAString& aAttrName, bool& aFound)
|
|
{
|
|
aFound = false;
|
|
NS_ENSURE_TRUE(mContent, nullptr);
|
|
|
|
nsRefPtr<mozilla::dom::NodeInfo> ni = mContent->GetExistingAttrNameFromQName(aAttrName);
|
|
if (!ni) {
|
|
return nullptr;
|
|
}
|
|
|
|
aFound = true;
|
|
return GetAttribute(ni, false);
|
|
}
|
|
|
|
bool
|
|
nsDOMAttributeMap::NameIsEnumerable(const nsAString& aName)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
Attr*
|
|
nsDOMAttributeMap::GetNamedItem(const nsAString& aAttrName)
|
|
{
|
|
bool dummy;
|
|
return NamedGetter(aAttrName, dummy);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsDOMAttributeMap::GetNamedItem(const nsAString& aAttrName,
|
|
nsIDOMAttr** aAttribute)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aAttribute);
|
|
|
|
NS_IF_ADDREF(*aAttribute = GetNamedItem(aAttrName));
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
void
|
|
nsDOMAttributeMap::EnsureAttributeCache()
|
|
{
|
|
if (!mAttributeCache) {
|
|
mAttributeCache = MakeUnique<AttrCache>();
|
|
}
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsDOMAttributeMap::SetNamedItem(nsIDOMAttr* aAttr, nsIDOMAttr** aReturn)
|
|
{
|
|
Attr* attribute = static_cast<Attr*>(aAttr);
|
|
NS_ENSURE_ARG(attribute);
|
|
|
|
ErrorResult rv;
|
|
*aReturn = SetNamedItem(*attribute, rv).take();
|
|
return rv.StealNSResult();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsDOMAttributeMap::SetNamedItemNS(nsIDOMAttr* aAttr, nsIDOMAttr** aReturn)
|
|
{
|
|
Attr* attribute = static_cast<Attr*>(aAttr);
|
|
NS_ENSURE_ARG(attribute);
|
|
|
|
ErrorResult rv;
|
|
*aReturn = SetNamedItemNS(*attribute, rv).take();
|
|
return rv.StealNSResult();
|
|
}
|
|
|
|
already_AddRefed<Attr>
|
|
nsDOMAttributeMap::SetNamedItemInternal(Attr& aAttr,
|
|
bool aWithNS,
|
|
ErrorResult& aError)
|
|
{
|
|
NS_ENSURE_TRUE(mContent, nullptr);
|
|
|
|
// XXX should check same-origin between mContent and aAttr however
|
|
// nsContentUtils::CheckSameOrigin can't deal with attributenodes yet
|
|
|
|
// Check that attribute is not owned by somebody else
|
|
nsDOMAttributeMap* owner = aAttr.GetMap();
|
|
if (owner) {
|
|
if (owner != this) {
|
|
aError.Throw(NS_ERROR_DOM_INUSE_ATTRIBUTE_ERR);
|
|
return nullptr;
|
|
}
|
|
|
|
// setting a preexisting attribute is a no-op, just return the same
|
|
// node.
|
|
nsRefPtr<Attr> attribute = &aAttr;
|
|
return attribute.forget();
|
|
}
|
|
|
|
nsresult rv;
|
|
if (mContent->OwnerDoc() != aAttr.OwnerDoc()) {
|
|
nsCOMPtr<nsINode> adoptedNode =
|
|
mContent->OwnerDoc()->AdoptNode(aAttr, aError);
|
|
if (aError.Failed()) {
|
|
return nullptr;
|
|
}
|
|
|
|
NS_ASSERTION(adoptedNode == &aAttr, "Uh, adopt node changed nodes?");
|
|
}
|
|
|
|
// Get nodeinfo and preexisting attribute (if it exists)
|
|
nsRefPtr<NodeInfo> oldNi;
|
|
|
|
if (!aWithNS) {
|
|
nsAutoString name;
|
|
aAttr.GetName(name);
|
|
oldNi = mContent->GetExistingAttrNameFromQName(name);
|
|
}
|
|
else {
|
|
uint32_t i, count = mContent->GetAttrCount();
|
|
for (i = 0; i < count; ++i) {
|
|
const nsAttrName* name = mContent->GetAttrNameAt(i);
|
|
int32_t attrNS = name->NamespaceID();
|
|
nsIAtom* nameAtom = name->LocalName();
|
|
|
|
// we're purposefully ignoring the prefix.
|
|
if (aAttr.NodeInfo()->Equals(nameAtom, attrNS)) {
|
|
oldNi = mContent->NodeInfo()->NodeInfoManager()->
|
|
GetNodeInfo(nameAtom, name->GetPrefix(), aAttr.NodeInfo()->NamespaceID(),
|
|
nsIDOMNode::ATTRIBUTE_NODE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
nsRefPtr<Attr> attr;
|
|
|
|
if (oldNi) {
|
|
nsRefPtr<Attr> oldAttr = GetAttribute(oldNi, true);
|
|
|
|
if (oldAttr == &aAttr) {
|
|
return oldAttr.forget();
|
|
}
|
|
|
|
if (oldAttr) {
|
|
attr = RemoveNamedItem(oldNi, aError);
|
|
NS_ASSERTION(attr->NodeInfo()->NameAndNamespaceEquals(oldNi),
|
|
"RemoveNamedItem() called, attr->NodeInfo() should be equal to oldNi!");
|
|
}
|
|
}
|
|
|
|
nsAutoString value;
|
|
aAttr.GetValue(value);
|
|
|
|
nsRefPtr<NodeInfo> ni = aAttr.NodeInfo();
|
|
|
|
// Add the new attribute to the attribute map before updating
|
|
// its value in the element. @see bug 364413.
|
|
nsAttrKey attrkey(ni->NamespaceID(), ni->NameAtom());
|
|
EnsureAttributeCache();
|
|
mAttributeCache->Put(attrkey, &aAttr);
|
|
aAttr.SetMap(this);
|
|
|
|
rv = mContent->SetAttr(ni->NamespaceID(), ni->NameAtom(),
|
|
ni->GetPrefixAtom(), value, true);
|
|
if (NS_FAILED(rv)) {
|
|
aError.Throw(rv);
|
|
DropAttribute(ni->NamespaceID(), ni->NameAtom());
|
|
}
|
|
|
|
return attr.forget();
|
|
}
|
|
|
|
already_AddRefed<Attr>
|
|
nsDOMAttributeMap::RemoveNamedItem(NodeInfo* aNodeInfo, ErrorResult& aError)
|
|
{
|
|
nsRefPtr<Attr> attribute = GetAttribute(aNodeInfo, true);
|
|
// This removes the attribute node from the attribute map.
|
|
aError = mContent->UnsetAttr(aNodeInfo->NamespaceID(), aNodeInfo->NameAtom(), true);
|
|
return attribute.forget();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsDOMAttributeMap::RemoveNamedItem(const nsAString& aName,
|
|
nsIDOMAttr** aReturn)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aReturn);
|
|
|
|
ErrorResult rv;
|
|
*aReturn = RemoveNamedItem(aName, rv).take();
|
|
return rv.StealNSResult();
|
|
}
|
|
|
|
already_AddRefed<Attr>
|
|
nsDOMAttributeMap::RemoveNamedItem(const nsAString& aName, ErrorResult& aError)
|
|
{
|
|
if (!mContent) {
|
|
aError.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<mozilla::dom::NodeInfo> ni = mContent->GetExistingAttrNameFromQName(aName);
|
|
if (!ni) {
|
|
aError.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
|
|
return nullptr;
|
|
}
|
|
|
|
return RemoveNamedItem(ni, aError);
|
|
}
|
|
|
|
|
|
Attr*
|
|
nsDOMAttributeMap::IndexedGetter(uint32_t aIndex, bool& aFound)
|
|
{
|
|
aFound = false;
|
|
NS_ENSURE_TRUE(mContent, nullptr);
|
|
|
|
const nsAttrName* name = mContent->GetAttrNameAt(aIndex);
|
|
NS_ENSURE_TRUE(name, nullptr);
|
|
|
|
aFound = true;
|
|
// Don't use the nodeinfo even if one exists since it can have the wrong
|
|
// owner document.
|
|
nsRefPtr<mozilla::dom::NodeInfo> ni = mContent->NodeInfo()->NodeInfoManager()->
|
|
GetNodeInfo(name->LocalName(), name->GetPrefix(), name->NamespaceID(),
|
|
nsIDOMNode::ATTRIBUTE_NODE);
|
|
return GetAttribute(ni, true);
|
|
}
|
|
|
|
Attr*
|
|
nsDOMAttributeMap::Item(uint32_t aIndex)
|
|
{
|
|
bool dummy;
|
|
return IndexedGetter(aIndex, dummy);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsDOMAttributeMap::Item(uint32_t aIndex, nsIDOMAttr** aReturn)
|
|
{
|
|
NS_IF_ADDREF(*aReturn = Item(aIndex));
|
|
return NS_OK;
|
|
}
|
|
|
|
uint32_t
|
|
nsDOMAttributeMap::Length() const
|
|
{
|
|
NS_ENSURE_TRUE(mContent, 0);
|
|
|
|
return mContent->GetAttrCount();
|
|
}
|
|
|
|
nsresult
|
|
nsDOMAttributeMap::GetLength(uint32_t *aLength)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aLength);
|
|
*aLength = Length();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsDOMAttributeMap::GetNamedItemNS(const nsAString& aNamespaceURI,
|
|
const nsAString& aLocalName,
|
|
nsIDOMAttr** aReturn)
|
|
{
|
|
NS_IF_ADDREF(*aReturn = GetNamedItemNS(aNamespaceURI, aLocalName));
|
|
return NS_OK;
|
|
}
|
|
|
|
Attr*
|
|
nsDOMAttributeMap::GetNamedItemNS(const nsAString& aNamespaceURI,
|
|
const nsAString& aLocalName)
|
|
{
|
|
nsRefPtr<mozilla::dom::NodeInfo> ni = GetAttrNodeInfo(aNamespaceURI, aLocalName);
|
|
if (!ni) {
|
|
return nullptr;
|
|
}
|
|
|
|
return GetAttribute(ni, true);
|
|
}
|
|
|
|
already_AddRefed<mozilla::dom::NodeInfo>
|
|
nsDOMAttributeMap::GetAttrNodeInfo(const nsAString& aNamespaceURI,
|
|
const nsAString& aLocalName)
|
|
{
|
|
if (!mContent) {
|
|
return nullptr;
|
|
}
|
|
|
|
int32_t nameSpaceID = kNameSpaceID_None;
|
|
|
|
if (!aNamespaceURI.IsEmpty()) {
|
|
nameSpaceID =
|
|
nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
|
|
|
|
if (nameSpaceID == kNameSpaceID_Unknown) {
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
uint32_t i, count = mContent->GetAttrCount();
|
|
for (i = 0; i < count; ++i) {
|
|
const nsAttrName* name = mContent->GetAttrNameAt(i);
|
|
int32_t attrNS = name->NamespaceID();
|
|
nsIAtom* nameAtom = name->LocalName();
|
|
|
|
// we're purposefully ignoring the prefix.
|
|
if (nameSpaceID == attrNS &&
|
|
nameAtom->Equals(aLocalName)) {
|
|
nsRefPtr<mozilla::dom::NodeInfo> ni;
|
|
ni = mContent->NodeInfo()->NodeInfoManager()->
|
|
GetNodeInfo(nameAtom, name->GetPrefix(), nameSpaceID,
|
|
nsIDOMNode::ATTRIBUTE_NODE);
|
|
|
|
return ni.forget();
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsDOMAttributeMap::RemoveNamedItemNS(const nsAString& aNamespaceURI,
|
|
const nsAString& aLocalName,
|
|
nsIDOMAttr** aReturn)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aReturn);
|
|
ErrorResult rv;
|
|
*aReturn = RemoveNamedItemNS(aNamespaceURI, aLocalName, rv).take();
|
|
return rv.StealNSResult();
|
|
}
|
|
|
|
already_AddRefed<Attr>
|
|
nsDOMAttributeMap::RemoveNamedItemNS(const nsAString& aNamespaceURI,
|
|
const nsAString& aLocalName,
|
|
ErrorResult& aError)
|
|
{
|
|
nsRefPtr<mozilla::dom::NodeInfo> ni = GetAttrNodeInfo(aNamespaceURI, aLocalName);
|
|
if (!ni) {
|
|
aError.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
|
|
return nullptr;
|
|
}
|
|
|
|
return RemoveNamedItem(ni, aError);
|
|
}
|
|
|
|
uint32_t
|
|
nsDOMAttributeMap::Count() const
|
|
{
|
|
return mAttributeCache ? mAttributeCache->Count() : 0;
|
|
}
|
|
|
|
uint32_t
|
|
nsDOMAttributeMap::Enumerate(AttrCache::EnumReadFunction aFunc,
|
|
void *aUserArg) const
|
|
{
|
|
return mAttributeCache ? mAttributeCache->EnumerateRead(aFunc, aUserArg) : 0;
|
|
}
|
|
|
|
size_t
|
|
AttrCacheSizeEnumerator(const nsAttrKey& aKey,
|
|
const nsRefPtr<Attr>& aValue,
|
|
MallocSizeOf aMallocSizeOf,
|
|
void* aUserArg)
|
|
{
|
|
return aMallocSizeOf(aValue.get());
|
|
}
|
|
|
|
size_t
|
|
nsDOMAttributeMap::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
|
|
{
|
|
size_t n = aMallocSizeOf(this);
|
|
n += mAttributeCache
|
|
? mAttributeCache->SizeOfExcludingThis(AttrCacheSizeEnumerator,
|
|
aMallocSizeOf)
|
|
: 0;
|
|
|
|
// NB: mContent is non-owning and thus not counted.
|
|
return n;
|
|
}
|
|
|
|
/* virtual */ JSObject*
|
|
nsDOMAttributeMap::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
|
{
|
|
return NamedNodeMapBinding::Wrap(aCx, this, aGivenProto);
|
|
}
|