зеркало из https://github.com/mozilla/gecko-dev.git
Bug 370372: function::name assignments now work under with (xmllist). r=brendan,jwalden.
This commit is contained in:
Родитель
a3997898ce
Коммит
06b4063e72
222
js/src/jsxml.c
222
js/src/jsxml.c
|
@ -4057,19 +4057,28 @@ SyncInScopeNamespaces(JSContext *cx, JSXML *xml)
|
|||
}
|
||||
|
||||
static JSBool
|
||||
GetNamedProperty(JSContext *cx, JSXML *xml, JSXMLQName* nameqn,
|
||||
JSBool attributes, JSXML *list)
|
||||
GetNamedProperty(JSContext *cx, JSXML *xml, JSXMLQName* nameqn, JSXML *list)
|
||||
{
|
||||
JSXMLArray *array;
|
||||
JSXMLNameMatcher matcher;
|
||||
JSXMLArrayCursor cursor;
|
||||
JSXML *kid;
|
||||
JSBool ok;
|
||||
JSBool attrs;
|
||||
|
||||
if (!JSXML_HAS_KIDS(xml))
|
||||
return JS_TRUE;
|
||||
|
||||
if (attributes) {
|
||||
if (xml->xml_class == JSXML_CLASS_LIST) {
|
||||
XMLArrayCursorInit(&cursor, &xml->xml_kids);
|
||||
while ((kid = (JSXML *) XMLArrayCursorNext(&cursor)) != NULL) {
|
||||
if (kid->xml_class == JSXML_CLASS_ELEMENT &&
|
||||
!GetNamedProperty(cx, kid, nameqn, list)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
XMLArrayCursorFinish(&cursor);
|
||||
if (kid)
|
||||
return JS_FALSE;
|
||||
} else if (xml->xml_class == JSXML_CLASS_ELEMENT) {
|
||||
attrs = (OBJ_GET_CLASS(cx, nameqn->object) == &js_AttributeNameClass);
|
||||
if (attrs) {
|
||||
array = &xml->xml_attrs;
|
||||
matcher = MatchAttrName;
|
||||
} else {
|
||||
|
@ -4080,21 +4089,21 @@ GetNamedProperty(JSContext *cx, JSXML *xml, JSXMLQName* nameqn,
|
|||
XMLArrayCursorInit(&cursor, array);
|
||||
while ((kid = (JSXML *) XMLArrayCursorNext(&cursor)) != NULL) {
|
||||
if (matcher(nameqn, kid)) {
|
||||
if (!attributes && kid->xml_class == JSXML_CLASS_ELEMENT) {
|
||||
ok = SyncInScopeNamespaces(cx, kid);
|
||||
if (!ok)
|
||||
goto out;
|
||||
if (!attrs &&
|
||||
kid->xml_class == JSXML_CLASS_ELEMENT &&
|
||||
!SyncInScopeNamespaces(cx, kid)) {
|
||||
break;
|
||||
}
|
||||
ok = Append(cx, list, kid);
|
||||
if (!ok)
|
||||
goto out;
|
||||
if (!Append(cx, list, kid))
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok = JS_TRUE;
|
||||
|
||||
out:
|
||||
XMLArrayCursorFinish(&cursor);
|
||||
return ok;
|
||||
if (kid)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* ECMA-357 9.1.1.1 XML [[Get]] and 9.2.1.1 XMLList [[Get]]. */
|
||||
|
@ -4108,8 +4117,6 @@ GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
jsid funid;
|
||||
jsval roots[2];
|
||||
JSTempValueRooter tvr;
|
||||
JSBool attributes;
|
||||
JSXMLArrayCursor cursor;
|
||||
|
||||
xml = (JSXML *) JS_GetInstancePrivate(cx, obj, &js_XMLClass, NULL);
|
||||
if (!xml)
|
||||
|
@ -4162,36 +4169,21 @@ GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
tvr.count++;
|
||||
|
||||
list = (JSXML *) JS_GetPrivate(cx, listobj);
|
||||
attributes = (OBJ_GET_CLASS(cx, nameqn->object) ==
|
||||
&js_AttributeNameClass);
|
||||
|
||||
if (xml->xml_class == JSXML_CLASS_LIST) {
|
||||
XMLArrayCursorInit(&cursor, &xml->xml_kids);
|
||||
while ((kid = (JSXML *) XMLArrayCursorNext(&cursor)) != NULL) {
|
||||
if (kid->xml_class == JSXML_CLASS_ELEMENT &&
|
||||
!GetNamedProperty(cx, kid, nameqn, attributes, list)) {
|
||||
if (!GetNamedProperty(cx, xml, nameqn, list)) {
|
||||
listobj = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
XMLArrayCursorFinish(&cursor);
|
||||
} else {
|
||||
if (!GetNamedProperty(cx, xml, nameqn, attributes, list))
|
||||
listobj = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Erratum: ECMA-357 9.1.1.1 misses that [[Append]] sets the given
|
||||
* list's [[TargetProperty]] to the property that is being appended.
|
||||
* This means that any use of the internal [[Get]] property returns
|
||||
* a list which, when used by e.g. [[Insert]] duplicates the last
|
||||
* element matched by id.
|
||||
* See bug 336921.
|
||||
* Erratum: ECMA-357 9.1.1.1 misses that [[Append]] sets the
|
||||
* given list's [[TargetProperty]] to the property that is being
|
||||
* appended. This means that any use of the internal [[Get]]
|
||||
* property returns a list which, when used by e.g. [[Insert]]
|
||||
* duplicates the last element matched by id. See bug 336921.
|
||||
*/
|
||||
list->xml_target = xml;
|
||||
list->xml_targetprop = nameqn;
|
||||
*vp = OBJECT_TO_JSVAL(listobj);
|
||||
}
|
||||
}
|
||||
|
||||
JS_POP_TEMP_ROOT(cx, &tvr);
|
||||
return listobj != NULL;
|
||||
|
@ -4270,10 +4262,16 @@ PutProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
roots[VAL_ROOT] = *vp;
|
||||
JS_PUSH_TEMP_ROOT(cx, 3, roots, &tvr);
|
||||
|
||||
if (xml->xml_class == JSXML_CLASS_LIST) {
|
||||
/* ECMA-357 9.2.1.2. */
|
||||
if (js_IdIsIndex(id, &index)) {
|
||||
/* Step 1 sets i to the property index. */
|
||||
if (xml->xml_class != JSXML_CLASS_LIST) {
|
||||
/* See NOTE in spec: this variation is reserved for future use. */
|
||||
ReportBadXMLName(cx, id);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/*
|
||||
* Step 1 of ECMA-357 9.2.1.2 index case sets i to the property index.
|
||||
*/
|
||||
i = index;
|
||||
|
||||
/* 2(a-b). */
|
||||
|
@ -4556,7 +4554,21 @@ PutProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
}
|
||||
} else {
|
||||
/*
|
||||
* 3.
|
||||
* ECMA-357 9.2.1.2/9.1.1.2 qname case.
|
||||
*/
|
||||
nameqn = ToXMLName(cx, id, &funid);
|
||||
if (!nameqn)
|
||||
goto bad;
|
||||
if (funid) {
|
||||
ok = js_SetProperty(cx, obj, funid, vp);
|
||||
goto out;
|
||||
}
|
||||
nameobj = nameqn->object;
|
||||
roots[ID_ROOT] = OBJECT_TO_JSVAL(nameqn);
|
||||
|
||||
if (xml->xml_class == JSXML_CLASS_LIST) {
|
||||
/*
|
||||
* Step 3 of 9.2.1.2.
|
||||
* Erratum: if x.[[Length]] > 1 or [[ResolveValue]] returns null
|
||||
* or an r with r.[[Length]] != 1, throw TypeError.
|
||||
*/
|
||||
|
@ -4574,36 +4586,23 @@ PutProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
goto out;
|
||||
}
|
||||
JS_ASSERT(JSXML_LENGTH(xml) == 1);
|
||||
kid = XMLARRAY_MEMBER(&xml->xml_kids, 0, JSXML);
|
||||
if (!kid)
|
||||
xml = XMLARRAY_MEMBER(&xml->xml_kids, 0, JSXML);
|
||||
if (!xml)
|
||||
goto out;
|
||||
kidobj = js_GetXMLObject(cx, kid);
|
||||
if (!kidobj)
|
||||
JS_ASSERT(xml->xml_class != JSXML_CLASS_LIST);
|
||||
obj = js_GetXMLObject(cx, xml);
|
||||
if (!obj)
|
||||
goto bad;
|
||||
ok = PutProperty(cx, kidobj, id, vp);
|
||||
if (!ok)
|
||||
goto out;
|
||||
roots[OBJ_ROOT] = OBJECT_TO_JSVAL(obj);
|
||||
|
||||
/* FALL THROUGH to non-list case */
|
||||
}
|
||||
} else {
|
||||
|
||||
/*
|
||||
* ECMA-357 9.1.1.2.
|
||||
* Erratum: move steps 3 and 4 to before 1 and 2, to avoid wasted
|
||||
* effort in ToString or [[DeepCopy]].
|
||||
*/
|
||||
if (js_IdIsIndex(id, &index)) {
|
||||
/* See NOTE in spec: this variation is reserved for future use. */
|
||||
ReportBadXMLName(cx, id);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
nameqn = ToXMLName(cx, id, &funid);
|
||||
if (!nameqn)
|
||||
goto bad;
|
||||
if (funid) {
|
||||
ok = js_SetProperty(cx, obj, funid, vp);
|
||||
goto out;
|
||||
}
|
||||
nameobj = nameqn->object;
|
||||
|
||||
if (JSXML_HAS_VALUE(xml))
|
||||
goto out;
|
||||
|
@ -4951,62 +4950,30 @@ ResolveValue(JSContext *cx, JSXML *list, JSXML **result)
|
|||
? OBJ_DROP_PROPERTY(cx, pobj, prop) \
|
||||
: (void) 0)
|
||||
|
||||
/* ECMA-357 9.1.1.6 XML [[HasProperty]] and 9.2.1.5 XMLList [[HasProperty]]. */
|
||||
static JSBool
|
||||
HasProperty(JSContext *cx, JSObject *obj, jsval id, JSObject **objp,
|
||||
JSProperty **propp)
|
||||
HasNamedProperty(JSXML *xml, JSXMLQName *nameqn)
|
||||
{
|
||||
JSXML *xml, *kid;
|
||||
JSBool found;
|
||||
JSXMLArrayCursor cursor;
|
||||
JSObject *kidobj;
|
||||
JSXMLQName *qn;
|
||||
jsid funid;
|
||||
JSXML *kid;
|
||||
JSXMLArray *array;
|
||||
JSXMLNameMatcher matcher;
|
||||
uint32 i, n;
|
||||
|
||||
*objp = NULL;
|
||||
*propp = NULL;
|
||||
|
||||
xml = (JSXML *) JS_GetPrivate(cx, obj);
|
||||
if (xml->xml_class == JSXML_CLASS_LIST) {
|
||||
n = JSXML_LENGTH(xml);
|
||||
if (js_IdIsIndex(id, &i)) {
|
||||
if (i < n)
|
||||
*propp = FOUND_XML_PROPERTY;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
found = JS_FALSE;
|
||||
XMLArrayCursorInit(&cursor, &xml->xml_kids);
|
||||
while ((kid = (JSXML *) XMLArrayCursorNext(&cursor)) != NULL) {
|
||||
if (kid->xml_class == JSXML_CLASS_ELEMENT) {
|
||||
kidobj = js_GetXMLObject(cx, kid);
|
||||
if (!kidobj || !HasProperty(cx, kidobj, id, objp, propp))
|
||||
found = HasNamedProperty(kid, nameqn);
|
||||
if (found)
|
||||
break;
|
||||
if (*propp)
|
||||
break;
|
||||
}
|
||||
}
|
||||
XMLArrayCursorFinish(&cursor);
|
||||
if (kid)
|
||||
return *propp != NULL;
|
||||
} else {
|
||||
if (xml->xml_class == JSXML_CLASS_ELEMENT && js_IdIsIndex(id, &i)) {
|
||||
if (i == 0)
|
||||
*propp = FOUND_XML_PROPERTY;
|
||||
return JS_TRUE;
|
||||
return found;
|
||||
}
|
||||
|
||||
qn = ToXMLName(cx, id, &funid);
|
||||
if (!qn)
|
||||
return JS_FALSE;
|
||||
if (funid)
|
||||
return js_LookupProperty(cx, obj, funid, objp, propp);
|
||||
|
||||
if (xml->xml_class != JSXML_CLASS_ELEMENT)
|
||||
return JS_TRUE;
|
||||
|
||||
if (OBJ_GET_CLASS(cx, qn->object) == &js_AttributeNameClass) {
|
||||
if (xml->xml_class == JSXML_CLASS_ELEMENT) {
|
||||
if (OBJ_GET_CLASS(cx, nameqn->object) == &js_AttributeNameClass) {
|
||||
array = &xml->xml_attrs;
|
||||
matcher = MatchAttrName;
|
||||
} else {
|
||||
|
@ -5015,13 +4982,46 @@ HasProperty(JSContext *cx, JSObject *obj, jsval id, JSObject **objp,
|
|||
}
|
||||
for (i = 0, n = array->length; i < n; i++) {
|
||||
kid = XMLARRAY_MEMBER(array, i, JSXML);
|
||||
if (kid && matcher(qn, kid)) {
|
||||
*propp = FOUND_XML_PROPERTY;
|
||||
if (kid && matcher(nameqn, kid))
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* ECMA-357 9.1.1.6 XML [[HasProperty]] and 9.2.1.5 XMLList [[HasProperty]]. */
|
||||
static JSBool
|
||||
HasProperty(JSContext *cx, JSObject *obj, jsval id, JSObject **objp,
|
||||
JSProperty **propp)
|
||||
{
|
||||
JSXML *xml;
|
||||
uint32 i;
|
||||
JSBool found;
|
||||
JSXMLQName *nameqn;
|
||||
jsid funid;
|
||||
|
||||
xml = (JSXML *) JS_GetPrivate(cx, obj);
|
||||
if (js_IdIsIndex(id, &i)) {
|
||||
if (xml->xml_class == JSXML_CLASS_LIST)
|
||||
found = (i < JSXML_LENGTH(xml));
|
||||
else if (xml->xml_class == JSXML_CLASS_ELEMENT)
|
||||
found = (i == 0);
|
||||
else
|
||||
found = JS_FALSE;
|
||||
} else {
|
||||
nameqn = ToXMLName(cx, id, &funid);
|
||||
if (!nameqn)
|
||||
return JS_FALSE;
|
||||
if (funid)
|
||||
return js_LookupProperty(cx, obj, funid, objp, propp);
|
||||
|
||||
found = HasNamedProperty(xml, nameqn);
|
||||
}
|
||||
|
||||
*objp = NULL;
|
||||
*propp = found ? FOUND_XML_PROPERTY : NULL;
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче