mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-07 07:04:09 +00:00
Bug 820846 - Modify the ListBase IC to work with [OverrideBuiltins] bindings, codegen changes and make HTMLDocument OverrideBuiltins. r=bz.
This commit is contained in:
parent
13326b1b78
commit
b33ba06a9d
@ -437,6 +437,14 @@ nsIdentifierMapEntry::RemoveNameElement(Element* aElement)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsIdentifierMapEntry::HasIdElementExposedAsHTMLDocumentProperty()
|
||||
{
|
||||
Element* idElement = GetIdElement();
|
||||
return idElement &&
|
||||
nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(idElement);
|
||||
}
|
||||
|
||||
// static
|
||||
size_t
|
||||
nsIdentifierMapEntry::SizeOfExcludingThis(nsIdentifierMapEntry* aEntry,
|
||||
@ -1784,6 +1792,9 @@ CustomPrototypeTrace(const nsAString& aName, JSObject* aObject, void *aArg)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDocument)
|
||||
CustomPrototypeTraceArgs customPrototypeArgs = { aCallback, aClosure };
|
||||
tmp->mCustomPrototypes.EnumerateRead(CustomPrototypeTrace, &customPrototypeArgs);
|
||||
if (tmp->PreservingWrapper()) {
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mExpandoAndGeneration.expando);
|
||||
}
|
||||
nsINode::Trace(tmp, aCallback, aClosure);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
@ -1848,6 +1859,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
|
||||
// else, and not unlink an awful lot here.
|
||||
|
||||
tmp->mIdentifierMap.Clear();
|
||||
++tmp->mExpandoAndGeneration.generation;
|
||||
tmp->mExpandoAndGeneration.expando = JS::UndefinedValue();
|
||||
|
||||
tmp->mCustomPrototypes.Clear();
|
||||
|
||||
@ -2725,11 +2738,19 @@ nsIDocument::GetLastModified(nsAString& aLastModified) const
|
||||
void
|
||||
nsDocument::AddToNameTable(Element *aElement, nsIAtom* aName)
|
||||
{
|
||||
MOZ_ASSERT(nsGenericHTMLElement::ShouldExposeNameAsHTMLDocumentProperty(aElement),
|
||||
"Only put elements that need to be exposed as document['name'] in "
|
||||
"the named table.");
|
||||
|
||||
nsIdentifierMapEntry *entry =
|
||||
mIdentifierMap.PutEntry(nsDependentAtomString(aName));
|
||||
|
||||
// Null for out-of-memory
|
||||
if (entry) {
|
||||
if (!entry->HasNameElement() &&
|
||||
!entry->HasIdElementExposedAsHTMLDocumentProperty()) {
|
||||
++mExpandoAndGeneration.generation;
|
||||
}
|
||||
entry->AddNameElement(this, aElement);
|
||||
}
|
||||
}
|
||||
@ -2747,6 +2768,10 @@ nsDocument::RemoveFromNameTable(Element *aElement, nsIAtom* aName)
|
||||
return;
|
||||
|
||||
entry->RemoveNameElement(aElement);
|
||||
if (!entry->HasNameElement() &&
|
||||
!entry->HasIdElementExposedAsHTMLDocumentProperty()) {
|
||||
++mExpandoAndGeneration.generation;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -2756,6 +2781,11 @@ nsDocument::AddToIdTable(Element *aElement, nsIAtom* aId)
|
||||
mIdentifierMap.PutEntry(nsDependentAtomString(aId));
|
||||
|
||||
if (entry) { /* True except on OOM */
|
||||
if (nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(aElement) &&
|
||||
!entry->HasNameElement() &&
|
||||
!entry->HasIdElementExposedAsHTMLDocumentProperty()) {
|
||||
++mExpandoAndGeneration.generation;
|
||||
}
|
||||
entry->AddIdElement(aElement);
|
||||
}
|
||||
}
|
||||
@ -2776,6 +2806,11 @@ nsDocument::RemoveFromIdTable(Element *aElement, nsIAtom* aId)
|
||||
return;
|
||||
|
||||
entry->RemoveIdElement(aElement);
|
||||
if (nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(aElement) &&
|
||||
!entry->HasNameElement() &&
|
||||
!entry->HasIdElementExposedAsHTMLDocumentProperty()) {
|
||||
++mExpandoAndGeneration.generation;
|
||||
}
|
||||
if (entry->IsEmpty()) {
|
||||
mIdentifierMap.RawRemoveEntry(entry);
|
||||
}
|
||||
@ -8122,6 +8157,7 @@ nsDocument::DestroyElementMaps()
|
||||
#endif
|
||||
mStyledLinks.Clear();
|
||||
mIdentifierMap.Clear();
|
||||
++mExpandoAndGeneration.generation;
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -178,6 +178,7 @@ public:
|
||||
* GetIdElement(true) if non-null.
|
||||
*/
|
||||
void SetImageElement(Element* aElement);
|
||||
bool HasIdElementExposedAsHTMLDocumentProperty();
|
||||
|
||||
bool HasContentChangeCallback() { return mChangeCallbacks != nullptr; }
|
||||
void AddContentChangeCallback(nsIDocument::IDTargetObserver aCallback,
|
||||
@ -1139,6 +1140,9 @@ public:
|
||||
virtual void SetTitle(const nsAString& aTitle, mozilla::ErrorResult& rv);
|
||||
|
||||
static void XPCOMShutdown();
|
||||
|
||||
js::ExpandoAndGeneration mExpandoAndGeneration;
|
||||
|
||||
protected:
|
||||
already_AddRefed<nsIPresShell> doCreateShell(nsPresContext* aContext,
|
||||
nsViewManager* aViewManager,
|
||||
|
@ -1047,16 +1047,6 @@ nsGenericHTMLElement::GetBaseTarget(nsAString& aBaseTarget) const
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
static bool
|
||||
CanHaveName(nsIAtom* aTag)
|
||||
{
|
||||
return aTag == nsGkAtoms::img ||
|
||||
aTag == nsGkAtoms::form ||
|
||||
aTag == nsGkAtoms::applet ||
|
||||
aTag == nsGkAtoms::embed ||
|
||||
aTag == nsGkAtoms::object;
|
||||
}
|
||||
|
||||
bool
|
||||
nsGenericHTMLElement::ParseAttribute(int32_t aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
|
@ -717,6 +717,20 @@ public:
|
||||
|
||||
static bool TouchEventsEnabled(JSContext* /* unused */, JSObject* /* unused */);
|
||||
|
||||
static inline bool
|
||||
CanHaveName(nsIAtom* aTag)
|
||||
{
|
||||
return aTag == nsGkAtoms::img ||
|
||||
aTag == nsGkAtoms::form ||
|
||||
aTag == nsGkAtoms::applet ||
|
||||
aTag == nsGkAtoms::embed ||
|
||||
aTag == nsGkAtoms::object;
|
||||
}
|
||||
static inline bool
|
||||
ShouldExposeNameAsHTMLDocumentProperty(Element* aElement)
|
||||
{
|
||||
return aElement->IsHTML() && CanHaveName(aElement->Tag());
|
||||
}
|
||||
static inline bool
|
||||
ShouldExposeIdAsHTMLDocumentProperty(Element* aElement)
|
||||
{
|
||||
|
@ -2385,10 +2385,8 @@ static PLDHashOperator
|
||||
IdentifierMapEntryAddNames(nsIdentifierMapEntry* aEntry, void* aArg)
|
||||
{
|
||||
nsTArray<nsString>* aNames = static_cast<nsTArray<nsString>*>(aArg);
|
||||
Element* idElement;
|
||||
if (aEntry->HasNameElement() ||
|
||||
((idElement = aEntry->GetIdElement()) &&
|
||||
nsGenericHTMLElement::ShouldExposeIdAsHTMLDocumentProperty(idElement))) {
|
||||
aEntry->HasIdElementExposedAsHTMLDocumentProperty()) {
|
||||
aNames->AppendElement(aEntry->GetKey());
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
|
@ -995,7 +995,10 @@ def finalizeHook(descriptor, hookName, context):
|
||||
finalize = "self->%s(%s);" % (hookName, context)
|
||||
else:
|
||||
finalize = "JSBindingFinalized<%s>::Finalized(self);\n" % descriptor.nativeType
|
||||
finalize += "ClearWrapper(self, self);\n" if descriptor.wrapperCache else ""
|
||||
if descriptor.wrapperCache:
|
||||
finalize += "ClearWrapper(self, self);\n"
|
||||
if descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
|
||||
finalize += "self->mExpandoAndGeneration.expando = JS::UndefinedValue();\n"
|
||||
if descriptor.workers:
|
||||
finalize += "self->Release();"
|
||||
elif descriptor.nativeOwnership == 'nsisupports':
|
||||
@ -2006,6 +2009,11 @@ def CreateBindingJSObject(descriptor, properties, parent):
|
||||
return NULL;
|
||||
}
|
||||
|
||||
"""
|
||||
if descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
|
||||
create += """ js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO,
|
||||
JS::PrivateValue(&aObject->mExpandoAndGeneration));
|
||||
|
||||
"""
|
||||
else:
|
||||
create = """ obj = JS_NewObject(aCx, &Class.mBase, proto, %s);
|
||||
@ -6234,9 +6242,7 @@ class CGResolveOwnProperty(CGAbstractMethod):
|
||||
]
|
||||
CGAbstractMethod.__init__(self, descriptor, "ResolveOwnProperty", "bool", args)
|
||||
def definition_body(self):
|
||||
return """ // We rely on getOwnPropertyDescriptor not shadowing prototype properties by named
|
||||
// properties. If that changes we'll need to filter here.
|
||||
return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc, flags);
|
||||
return """ return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc, flags);
|
||||
"""
|
||||
|
||||
class CGEnumerateOwnProperties(CGAbstractMethod):
|
||||
@ -6247,9 +6253,7 @@ class CGEnumerateOwnProperties(CGAbstractMethod):
|
||||
Argument('JS::AutoIdVector&', 'props')]
|
||||
CGAbstractMethod.__init__(self, descriptor, "EnumerateOwnProperties", "bool", args)
|
||||
def definition_body(self):
|
||||
return """ // We rely on getOwnPropertyNames not shadowing prototype properties by named
|
||||
// properties. If that changes we'll need to filter here.
|
||||
return js::GetProxyHandler(obj)->getOwnPropertyNames(cx, wrapper, props);
|
||||
return """ return js::GetProxyHandler(obj)->getOwnPropertyNames(cx, wrapper, props);
|
||||
"""
|
||||
|
||||
class CGPrototypeTraitsClass(CGClass):
|
||||
@ -6584,10 +6588,10 @@ MOZ_ASSERT_IF(desc->obj, desc->obj == ${holder});"""
|
||||
fillDescriptor = "FillPropertyDescriptor(desc, proxy, %s);\nreturn true;" % readonly
|
||||
templateValues = {'jsvalRef': 'desc->value', 'jsvalPtr': '&desc->value',
|
||||
'obj': 'proxy', 'successCode': fillDescriptor}
|
||||
# Once we start supporting OverrideBuiltins we need to make
|
||||
# ResolveOwnProperty or EnumerateOwnProperties filter out named
|
||||
# properties that shadow prototype properties.
|
||||
condition = "!(flags & JSRESOLVE_ASSIGNING) && !HasPropertyOnPrototype(cx, proxy, this, id)"
|
||||
condition = "!HasPropertyOnPrototype(cx, proxy, this, id)"
|
||||
if self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
|
||||
condition = "(!isXray || %s)" % condition
|
||||
condition = "!(flags & JSRESOLVE_ASSIGNING) && " + condition
|
||||
if self.descriptor.supportsIndexedProperties():
|
||||
condition = "!IsArrayIndex(index) && " + condition
|
||||
namedGet = ("\n" +
|
||||
@ -6745,14 +6749,16 @@ class CGDOMJSProxyHandler_delete(ClassMethod):
|
||||
# We always return above for an index id in the case when we support
|
||||
# indexed properties, so we can just treat the id as a name
|
||||
# unconditionally here.
|
||||
delete += ("if (!HasPropertyOnPrototype(cx, proxy, this, id)) {\n" +
|
||||
CGIndenter(CGGeneric(namedBody)).define() + "\n"
|
||||
" if (found) {\n"
|
||||
" return true;\n"
|
||||
" }\n"
|
||||
delete += (CGGeneric(namedBody).define() + "\n"
|
||||
"if (found) {\n"
|
||||
" return true;\n"
|
||||
"}\n")
|
||||
if not self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
|
||||
delete = CGIfWrapper(CGGeneric(delete),
|
||||
"!HasPropertyOnPrototype(cx, proxy, this, id)").define()
|
||||
delete += """
|
||||
|
||||
delete += "return dom::DOMProxyHandler::delete_(cx, proxy, id, bp);";
|
||||
return dom::DOMProxyHandler::delete_(cx, proxy, id, bp);"""
|
||||
|
||||
return delete
|
||||
|
||||
@ -6779,13 +6785,17 @@ for (int32_t i = 0; i < int32_t(length); ++i) {
|
||||
addIndices = ""
|
||||
|
||||
if self.descriptor.supportsNamedProperties():
|
||||
if self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
|
||||
shadow = "!isXray"
|
||||
else:
|
||||
shadow = "false"
|
||||
addNames = """
|
||||
nsTArray<nsString> names;
|
||||
UnwrapProxy(proxy)->GetSupportedNames(names);
|
||||
if (!AppendNamedPropertyIds(cx, proxy, names, props)) {
|
||||
if (!AppendNamedPropertyIds(cx, proxy, names, %s, props)) {
|
||||
return false;
|
||||
}
|
||||
"""
|
||||
""" % shadow
|
||||
else:
|
||||
addNames = ""
|
||||
|
||||
@ -6842,14 +6852,15 @@ class CGDOMJSProxyHandler_hasOwn(ClassMethod):
|
||||
if self.descriptor.supportsNamedProperties():
|
||||
# If we support indexed properties we always return above for index
|
||||
# property names, so no need to check for those here.
|
||||
named = ("if (!HasPropertyOnPrototype(cx, proxy, this, id)) {\n" +
|
||||
CGIndenter(CGProxyNamedPresenceChecker(self.descriptor)).define() + "\n" +
|
||||
" *bp = found;\n"
|
||||
" return true;\n"
|
||||
"}\n" +
|
||||
"\n")
|
||||
named = (CGProxyNamedPresenceChecker(self.descriptor).define() + "\n" +
|
||||
"*bp = found;\n")
|
||||
if not self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
|
||||
named = CGIfWrapper(CGGeneric(named + "return true;\n"),
|
||||
"!HasPropertyOnPrototype(cx, proxy, this, id)").define()
|
||||
named += ("\n"
|
||||
"*bp = false;")
|
||||
else:
|
||||
named = ""
|
||||
named = "*bp = false;"
|
||||
|
||||
return """MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
|
||||
"Should not have a XrayWrapper here");
|
||||
@ -6865,7 +6876,7 @@ if (expando) {
|
||||
}
|
||||
}
|
||||
|
||||
""" + named + """*bp = false;
|
||||
""" + named + """
|
||||
return true;"""
|
||||
|
||||
class CGDOMJSProxyHandler_get(ClassMethod):
|
||||
@ -6915,35 +6926,39 @@ if (expando) {
|
||||
} else {
|
||||
%s
|
||||
}
|
||||
|
||||
""" % (stripTrailingWhitespace(getUnforgeableOrExpando.replace('\n', '\n ')))
|
||||
else:
|
||||
getIndexedOrExpando = getUnforgeableOrExpando + "\n"
|
||||
getIndexedOrExpando = getUnforgeableOrExpando + "\n\n"
|
||||
|
||||
if self.descriptor.supportsNamedProperties():
|
||||
getNamed = CGProxyNamedGetter(self.descriptor, templateValues)
|
||||
if self.descriptor.supportsIndexedProperties():
|
||||
getNamed = CGIfWrapper(getNamed, "!IsArrayIndex(index)")
|
||||
getNamed = getNamed.define() + "\n"
|
||||
getNamed = getNamed.define() + "\n\n"
|
||||
else:
|
||||
getNamed = ""
|
||||
|
||||
getOnPrototype = """bool foundOnPrototype;
|
||||
if (!GetPropertyOnPrototype(cx, proxy, id, &foundOnPrototype, vp.address())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (foundOnPrototype) {
|
||||
return true;
|
||||
}
|
||||
|
||||
"""
|
||||
if self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
|
||||
getNamed = getNamed + getOnPrototype
|
||||
else:
|
||||
getNamed = getOnPrototype + getNamed
|
||||
|
||||
return """MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
|
||||
"Should not have a XrayWrapper here");
|
||||
|
||||
%s
|
||||
{ // Scope for this "found" so it doesn't leak to things below
|
||||
bool found;
|
||||
if (!GetPropertyOnPrototype(cx, proxy, id, &found, vp.address())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
%s
|
||||
vp.setUndefined();
|
||||
return true;""" % (getIndexedOrExpando, getNamed)
|
||||
""" + getIndexedOrExpando + getNamed + """vp.setUndefined();
|
||||
return true;"""
|
||||
|
||||
class CGDOMJSProxyHandler_className(ClassMethod):
|
||||
def __init__(self, descriptor):
|
||||
|
@ -75,11 +75,25 @@ SetListBaseInformation gSetListBaseInformation;
|
||||
JSObject*
|
||||
DOMProxyHandler::GetAndClearExpandoObject(JSObject* obj)
|
||||
{
|
||||
JSObject* expando = GetExpandoObject(obj);
|
||||
XPCWrappedNativeScope* scope = xpc::GetObjectScope(obj);
|
||||
scope->RemoveDOMExpandoObject(obj);
|
||||
js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, UndefinedValue());
|
||||
return expando;
|
||||
MOZ_ASSERT(IsDOMProxy(obj), "expected a DOM proxy object");
|
||||
JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
|
||||
if (v.isUndefined()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (v.isObject()) {
|
||||
js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, UndefinedValue());
|
||||
return &v.toObject();
|
||||
}
|
||||
|
||||
js::ExpandoAndGeneration* expandoAndGeneration =
|
||||
static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
|
||||
v = expandoAndGeneration->expando;
|
||||
if (v.isUndefined()) {
|
||||
return nullptr;
|
||||
}
|
||||
expandoAndGeneration->expando = UndefinedValue();
|
||||
return &v.toObject();
|
||||
}
|
||||
|
||||
// static
|
||||
@ -87,25 +101,42 @@ JSObject*
|
||||
DOMProxyHandler::EnsureExpandoObject(JSContext* cx, JS::Handle<JSObject*> obj)
|
||||
{
|
||||
NS_ASSERTION(IsDOMProxy(obj), "expected a DOM proxy object");
|
||||
JS::Rooted<JSObject*> expando(cx, GetExpandoObject(obj));
|
||||
JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
|
||||
if (v.isObject()) {
|
||||
return &v.toObject();
|
||||
}
|
||||
|
||||
js::ExpandoAndGeneration* expandoAndGeneration;
|
||||
if (!v.isUndefined()) {
|
||||
expandoAndGeneration = static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
|
||||
if (expandoAndGeneration->expando.isObject()) {
|
||||
return &expandoAndGeneration->expando.toObject();
|
||||
}
|
||||
} else {
|
||||
expandoAndGeneration = nullptr;
|
||||
}
|
||||
|
||||
JSObject* expando = JS_NewObjectWithGivenProto(cx, nullptr, nullptr,
|
||||
js::GetObjectParent(obj));
|
||||
if (!expando) {
|
||||
expando = JS_NewObjectWithGivenProto(cx, nullptr, nullptr,
|
||||
js::GetObjectParent(obj));
|
||||
if (!expando) {
|
||||
return NULL;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
XPCWrappedNativeScope* scope = xpc::GetObjectScope(obj);
|
||||
if (!scope->RegisterDOMExpandoObject(obj)) {
|
||||
return NULL;
|
||||
}
|
||||
XPCWrappedNativeScope* scope = xpc::GetObjectScope(obj);
|
||||
if (!scope->RegisterDOMExpandoObject(obj)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsWrapperCache* cache;
|
||||
CallQueryInterface(UnwrapDOMObject<nsISupports>(obj), &cache);
|
||||
cache->SetPreservingWrapper(true);
|
||||
nsWrapperCache* cache;
|
||||
CallQueryInterface(UnwrapDOMObject<nsISupports>(obj), &cache);
|
||||
cache->SetPreservingWrapper(true);
|
||||
|
||||
if (expandoAndGeneration) {
|
||||
expandoAndGeneration->expando.setObject(*expando);
|
||||
} else {
|
||||
js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, ObjectValue(*expando));
|
||||
}
|
||||
|
||||
return expando;
|
||||
}
|
||||
|
||||
@ -234,6 +265,7 @@ bool
|
||||
DOMProxyHandler::AppendNamedPropertyIds(JSContext* cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
nsTArray<nsString>& names,
|
||||
bool shadowPrototypeProperties,
|
||||
JS::AutoIdVector& props)
|
||||
{
|
||||
for (uint32_t i = 0; i < names.Length(); ++i) {
|
||||
@ -247,7 +279,8 @@ DOMProxyHandler::AppendNamedPropertyIds(JSContext* cx,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!HasPropertyOnPrototype(cx, proxy, this, id)) {
|
||||
if (shadowPrototypeProperties ||
|
||||
!HasPropertyOnPrototype(cx, proxy, this, id)) {
|
||||
if (!props.append(id)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -51,7 +51,18 @@ public:
|
||||
{
|
||||
MOZ_ASSERT(IsDOMProxy(obj), "expected a DOM proxy object");
|
||||
JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
|
||||
return v.isUndefined() ? NULL : v.toObjectOrNull();
|
||||
if (v.isObject()) {
|
||||
return &v.toObject();
|
||||
}
|
||||
|
||||
if (v.isUndefined()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
js::ExpandoAndGeneration* expandoAndGeneration =
|
||||
static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
|
||||
v = expandoAndGeneration->expando;
|
||||
return v.isUndefined() ? nullptr : &v.toObject();
|
||||
}
|
||||
static JSObject* GetAndClearExpandoObject(JSObject* obj);
|
||||
static JSObject* EnsureExpandoObject(JSContext* cx,
|
||||
@ -60,10 +71,12 @@ public:
|
||||
const DOMClass& mClass;
|
||||
|
||||
protected:
|
||||
// Append the property names in "names" that don't live on our proto
|
||||
// chain to "props"
|
||||
// Append the property names in "names" to "props". If
|
||||
// shadowPrototypeProperties is false then skip properties that are also
|
||||
// present on our proto chain.
|
||||
bool AppendNamedPropertyIds(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
nsTArray<nsString>& names,
|
||||
bool shadowPrototypeProperties,
|
||||
JS::AutoIdVector& props);
|
||||
};
|
||||
|
||||
|
@ -903,7 +903,8 @@ class IDLInterface(IDLObjectWithScope):
|
||||
identifier == "NeedNewResolve" or
|
||||
identifier == "JSImplementation" or
|
||||
identifier == "HeaderFile" or
|
||||
identifier == "NavigatorProperty"):
|
||||
identifier == "NavigatorProperty" or
|
||||
identifier == "OverrideBuiltins"):
|
||||
# Known attributes that we don't need to do anything with here
|
||||
pass
|
||||
else:
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
interface Selection;
|
||||
|
||||
[OverrideBuiltins]
|
||||
interface HTMLDocument : Document {
|
||||
[Throws]
|
||||
attribute DOMString? domain;
|
||||
|
Loading…
x
Reference in New Issue
Block a user