added XMLGraph and XMLParser JS/XML glue
git-svn-id: svn://10.0.0.236/trunk@7054 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
30
mozilla/modules/xml/js/Makefile
Normal file
30
mozilla/modules/xml/js/Makefile
Normal file
@@ -0,0 +1,30 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH = ../../..
|
||||
REQUIRES = xmlparse xmltok expat js
|
||||
CSRCS = jsxparse.c \
|
||||
jsxgraph.c \
|
||||
xmljs.c \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = xmljs.h
|
||||
LIBRARY_NAME = xmljs
|
||||
MODULE = xmljs
|
||||
|
||||
include $(DEPTH)/config/rules.mk
|
||||
|
||||
10
mozilla/modules/xml/js/README
Normal file
10
mozilla/modules/xml/js/README
Normal file
@@ -0,0 +1,10 @@
|
||||
Some primitive JS/XML glue. Contact shaver@netscape.com.
|
||||
|
||||
XMLParser: a thin wrapper around the parser APIs of James Clark's `expat'
|
||||
XML parser.
|
||||
|
||||
XMLGraph: JSClass that generates a simple JS object graph from XML. This is
|
||||
NOT W3C Level 1 DOM compliant by any stretch of even my vivid
|
||||
imagination.
|
||||
|
||||
These objects may never show up in Mozilla, of course.
|
||||
264
mozilla/modules/xml/js/jsxgraph.c
Normal file
264
mozilla/modules/xml/js/jsxgraph.c
Normal file
@@ -0,0 +1,264 @@
|
||||
#define XMLJS_INTERNAL
|
||||
#include "xmljs.h"
|
||||
#undef XMLJS_INTERNAL
|
||||
|
||||
#if DEBUG_shaver
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* An XMLGraph JS object produces an object graph in response
|
||||
* to XML parser events.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
XMLCallback cb;
|
||||
JSObject *current;
|
||||
char *nameBy;
|
||||
} XMLGraphCallback;
|
||||
|
||||
static char
|
||||
xmlg_up_str[] = "__up__";
|
||||
|
||||
static void
|
||||
StartElementHandler(void *userdata, const char *name, const char **atts)
|
||||
{
|
||||
XMLGraphCallback * cb = (XMLGraphCallback *)userdata;
|
||||
int i;
|
||||
JSObject *element, *attobj, *array;
|
||||
JSContext *cx = cb->cb.cx;
|
||||
jsval rval;
|
||||
|
||||
if (!cb->current) {
|
||||
if (!JS_EvaluateScript(cx, JS_GetGlobalObject(cx), xmljs_newObj_str,
|
||||
xmljs_newObj_size,
|
||||
"XMLGraph internal", 0, &rval)) {
|
||||
JS_ReportError(cx, "failed to create new Object");
|
||||
return;
|
||||
}
|
||||
element = JSVAL_TO_OBJECT(rval);
|
||||
cb->current = element;
|
||||
if (!JS_DefineProperty(cx, cb->cb.obj, "graph", rval,
|
||||
NULL, NULL, JSPROP_ENUMERATE)) {
|
||||
JS_ReportError(cx, "failed to define graph prop");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!JS_EvaluateScript(cx, JS_GetGlobalObject(cx), xmljs_newObj_str,
|
||||
xmljs_newObj_size,
|
||||
"XMLGraph internal", 0, &rval)) {
|
||||
JS_ReportError(cx, "failed to create new Object");
|
||||
return;
|
||||
}
|
||||
element = JSVAL_TO_OBJECT(rval);
|
||||
|
||||
/* populate and set __attributes__ */
|
||||
if (atts[0]) {
|
||||
JSString *attstr;
|
||||
if (!JS_EvaluateScript(cx, JS_GetGlobalObject(cx), xmljs_newObj_str,
|
||||
xmljs_newObj_size,
|
||||
"XMLGraph internal", 0, &rval))
|
||||
return;
|
||||
attobj = JSVAL_TO_OBJECT(rval);
|
||||
|
||||
for (i = 0; atts[i]; i+=2) {
|
||||
/*
|
||||
* if we have an attribute that matches nameBy, use
|
||||
* the value of that attribute to name the node
|
||||
*/
|
||||
if (cb->nameBy && !strcmp(cb->nameBy, atts[i]))
|
||||
name = atts[i+1];
|
||||
|
||||
attstr = JS_NewStringCopyZ(cx, atts[i+1]);
|
||||
if (!attstr ||
|
||||
!JS_DefineProperty(cx, attobj, atts[i],
|
||||
STRING_TO_JSVAL(attstr),
|
||||
NULL, NULL, JSPROP_ENUMERATE))
|
||||
return;
|
||||
}
|
||||
if (!JS_DefineProperty(cx, element, "__attributes__",
|
||||
OBJECT_TO_JSVAL(attobj), NULL, NULL,
|
||||
0))
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check for existing property with this name */
|
||||
if (!JS_GetProperty(cx, cb->current, name, &rval))
|
||||
return;
|
||||
|
||||
if (JSVAL_IS_OBJECT(rval)) {
|
||||
JSObject *existing = JSVAL_TO_OBJECT(rval);
|
||||
if (JS_IsArrayObject(cx, existing)) {
|
||||
/* already an array, so append */
|
||||
jsuint length;
|
||||
if (!JS_GetArrayLength(cx, existing, &length) ||
|
||||
!JS_DefineElement(cx, existing, (jsint)length,
|
||||
OBJECT_TO_JSVAL(element), NULL, NULL,
|
||||
JSPROP_ENUMERATE))
|
||||
return;
|
||||
} else {
|
||||
/* replace with an array [current, new] */
|
||||
jsval vector[2];
|
||||
vector[0] = OBJECT_TO_JSVAL(existing);
|
||||
vector[1] = OBJECT_TO_JSVAL(element);
|
||||
array = JS_NewArrayObject(cx, 2, vector);
|
||||
if (!array ||
|
||||
!JS_DefineProperty(cx, cb->current, name,
|
||||
OBJECT_TO_JSVAL(array), NULL, NULL,
|
||||
JSPROP_ENUMERATE))
|
||||
return;
|
||||
}
|
||||
} else if (!JS_DefineProperty(cx, cb->current, name,
|
||||
OBJECT_TO_JSVAL(element), NULL, NULL,
|
||||
JSPROP_ENUMERATE))
|
||||
return;
|
||||
|
||||
/* define backpointer __up__ */
|
||||
if (!JS_DefineProperty(cx, element, xmlg_up_str,
|
||||
OBJECT_TO_JSVAL(cb->current),
|
||||
NULL, NULL, 0))
|
||||
return;
|
||||
/*
|
||||
* XXX DefineProperty(element, "__element__", elementstr)
|
||||
*/
|
||||
|
||||
cb->current = element;
|
||||
}
|
||||
|
||||
static void
|
||||
EndElementHandler(void *userdata, const char *name)
|
||||
{
|
||||
/* XXX check to be sure that it's the right one ending! */
|
||||
XMLGraphCallback *cb = (XMLGraphCallback *)userdata;
|
||||
JSContext *cx = cb->cb.cx;
|
||||
jsval rval;
|
||||
|
||||
if (!JS_GetProperty(cx, cb->current, xmlg_up_str, &rval))
|
||||
return;
|
||||
cb->current = JSVAL_TO_OBJECT(rval);
|
||||
}
|
||||
|
||||
static void
|
||||
CharacterDataHandler(void *userdata, const char *s, int len)
|
||||
{
|
||||
XMLGraphCallback *cb = (XMLGraphCallback *)userdata;
|
||||
JSString *str;
|
||||
JSContext *cx = cb->cb.cx;
|
||||
|
||||
str = JS_NewStringCopyN(cx, s, len);
|
||||
if (!str)
|
||||
return;
|
||||
JS_DefineProperty(cx, cb->current, "__cdata__", STRING_TO_JSVAL(str),
|
||||
NULL, NULL, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
ProcessingInstructionHandler(void *userdata, const char *target,
|
||||
const char *data)
|
||||
{
|
||||
/*
|
||||
* (cb->obj).processingInstruction(element, target, data)
|
||||
*/
|
||||
}
|
||||
|
||||
static JSBool
|
||||
PreParse(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
XMLGraphCallback *cb;
|
||||
if (!JS_DeleteProperty(cx, obj, "graph"))
|
||||
return JS_FALSE;
|
||||
cb = (XMLGraphCallback *)JS_GetPrivate(cx, obj);
|
||||
if (!cb)
|
||||
return JS_FALSE;
|
||||
cb->current = NULL;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
XMLGraph(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
XMLGraphCallback *cb = JS_malloc(cx, sizeof(XMLGraphCallback));
|
||||
if (!cb)
|
||||
return JS_FALSE;
|
||||
cb->cb.xml = NULL;
|
||||
cb->cb.obj = obj;
|
||||
cb->cb.cx = cx;
|
||||
cb->current = NULL;
|
||||
cb->nameBy = NULL;
|
||||
cb->cb.start = StartElementHandler;
|
||||
cb->cb.end = EndElementHandler;
|
||||
cb->cb.cdata = CharacterDataHandler;
|
||||
cb->cb.processing = ProcessingInstructionHandler;
|
||||
cb->cb.preParse = PreParse;
|
||||
cb->cb.postParse = NULL;
|
||||
return JS_SetPrivate(cx, obj, (void *)cb);
|
||||
}
|
||||
|
||||
static void
|
||||
xmlgraph_finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
XMLGraphCallback *cb;
|
||||
cb = (XMLGraphCallback *)JS_GetPrivate(cx, obj);
|
||||
if (!cb)
|
||||
return;
|
||||
if (cb->nameBy)
|
||||
JS_free(cx, cb->nameBy);
|
||||
JS_free(cx, cb);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
xmlgraph_nameBySetter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
{
|
||||
JSString *namestr;
|
||||
XMLGraphCallback *cb = JS_GetPrivate(cx, obj);
|
||||
if (!cb)
|
||||
return JS_TRUE;
|
||||
if (*vp == JSVAL_NULL) {
|
||||
if (cb->nameBy)
|
||||
JS_free(cx, cb->nameBy);
|
||||
cb->nameBy = NULL;
|
||||
return JS_TRUE;
|
||||
}
|
||||
namestr = JS_ValueToString(cx, *vp);
|
||||
if (!namestr)
|
||||
return JS_FALSE;
|
||||
if (cb->nameBy)
|
||||
JS_free(cx, cb->nameBy);
|
||||
cb->nameBy = JS_strdup(cx, JS_GetStringBytes(namestr));
|
||||
if (!cb->nameBy)
|
||||
return JS_FALSE;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSClass XMLGraph_class = {
|
||||
"XMLGraph", JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, xmlgraph_finalize
|
||||
};
|
||||
|
||||
JSFunctionSpec xmlgraph_funcs[] = {
|
||||
{0}
|
||||
};
|
||||
|
||||
JSPropertySpec xmlgraph_props[] = {
|
||||
{"nameBy", -1, JSPROP_ENUMERATE, NULL, xmlgraph_nameBySetter},
|
||||
{0}
|
||||
};
|
||||
|
||||
JSBool
|
||||
XMLGraph_Init(JSContext *cx, JSObject *obj, JSObject *parent_proto)
|
||||
{
|
||||
jsval v = JSVAL_NULL;
|
||||
JSObject *proto = JS_InitClass(cx, obj, parent_proto, &XMLGraph_class,
|
||||
XMLGraph, 1,
|
||||
xmlgraph_props, xmlgraph_funcs,
|
||||
NULL, NULL);
|
||||
|
||||
if (!proto)
|
||||
return JS_FALSE;
|
||||
if (!JS_SetProperty(cx, proto, "nameBy", &v)) {
|
||||
JS_ReportError(cx, "failed to set XMLGraph.prototype.nameBy = null");
|
||||
return JS_FALSE;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
218
mozilla/modules/xml/js/jsxparse.c
Normal file
218
mozilla/modules/xml/js/jsxparse.c
Normal file
@@ -0,0 +1,218 @@
|
||||
#define XMLJS_INTERNAL
|
||||
#include "xmljs.h"
|
||||
#undef XMLJS_INTERNAL
|
||||
|
||||
static void
|
||||
StartElementHandler(void *userdata, const char *name, const char **atts)
|
||||
{
|
||||
XMLCallback *cb = (XMLCallback *)userdata;
|
||||
int i;
|
||||
JSString *namestr = NULL, *attstr = NULL;
|
||||
JSObject *attobj = NULL;
|
||||
JSContext *cx = cb->cx;
|
||||
jsval argv[2];
|
||||
jsval rval;
|
||||
JSFunction *fun;
|
||||
|
||||
if (!JS_GetProperty(cx, cb->obj, "startElement", &rval) ||
|
||||
JSVAL_IS_VOID(rval) || JSVAL_IS_NULL(rval))
|
||||
return;
|
||||
|
||||
fun = JS_ValueToFunction(cx, rval);
|
||||
if (!fun)
|
||||
return;
|
||||
|
||||
/* oh, for local roots */
|
||||
JS_AddRoot(cx, &namestr);
|
||||
JS_AddRoot(cx, &attobj);
|
||||
JS_AddRoot(cx, &attstr);
|
||||
|
||||
namestr = JS_NewStringCopyZ(cx, name);
|
||||
|
||||
if (atts[0]) {
|
||||
if (!JS_EvaluateScript(cx, JS_GetGlobalObject(cx), xmljs_newObj_str,
|
||||
xmljs_newObj_size,
|
||||
"XMLParser internal", 0, &rval)) {
|
||||
JS_ReportError(cx, "failed to create attobj");
|
||||
goto out;
|
||||
}
|
||||
attobj = JSVAL_TO_OBJECT(rval);
|
||||
|
||||
for (i = 0; atts[i]; i+=2) {
|
||||
attstr = JS_NewStringCopyZ(cx, atts[i+1]);
|
||||
if (!attstr ||
|
||||
!JS_DefineProperty(cx, attobj, atts[i],
|
||||
STRING_TO_JSVAL(attstr),
|
||||
NULL, NULL, JSPROP_ENUMERATE)) {
|
||||
JS_ReportError(cx, "defining att prop %s failed", atts[i]);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
argv[0] = STRING_TO_JSVAL(namestr);
|
||||
argv[1] = OBJECT_TO_JSVAL(attobj);
|
||||
JS_CallFunction(cx, cb->obj, fun, 2, argv, &rval);
|
||||
|
||||
out:
|
||||
JS_RemoveRoot(cx, &namestr);
|
||||
JS_RemoveRoot(cx, &attstr);
|
||||
JS_RemoveRoot(cx, &attobj);
|
||||
}
|
||||
|
||||
static void
|
||||
EndElementHandler(void *userdata, const char *name)
|
||||
{
|
||||
XMLCallback *cb = (XMLCallback *)userdata;
|
||||
JSString *namestr = NULL;
|
||||
JSContext *cx = cb->cx;
|
||||
jsval argv[1];
|
||||
jsval rval;
|
||||
JSFunction *fun;
|
||||
|
||||
if (!JS_GetProperty(cx, cb->obj, "endElement", &rval) ||
|
||||
JSVAL_IS_VOID(rval) || JSVAL_IS_NULL(rval))
|
||||
return;
|
||||
|
||||
fun = JS_ValueToFunction(cx, rval);
|
||||
if (!fun)
|
||||
return;
|
||||
|
||||
/* oh, for local roots */
|
||||
JS_AddRoot(cx, &namestr);
|
||||
|
||||
namestr = JS_NewStringCopyZ(cx, name);
|
||||
if (!namestr)
|
||||
goto out;
|
||||
argv[0] = STRING_TO_JSVAL(namestr);
|
||||
JS_CallFunction(cx, cb->obj, fun, 1, argv, &rval);
|
||||
|
||||
out:
|
||||
JS_RemoveRoot(cx, &namestr);
|
||||
}
|
||||
|
||||
static void
|
||||
CharacterDataHandler(void *userdata, const char *s, int len)
|
||||
{
|
||||
XMLCallback *cb = (XMLCallback *)userdata;
|
||||
JSString *cdatastr = NULL;
|
||||
JSContext *cx = cb->cx;
|
||||
jsval argv[1];
|
||||
jsval rval;
|
||||
JSFunction *fun;
|
||||
|
||||
if (!JS_GetProperty(cx, cb->obj, "characterData", &rval) ||
|
||||
JSVAL_IS_VOID(rval) || JSVAL_IS_NULL(rval))
|
||||
return;
|
||||
|
||||
fun = JS_ValueToFunction(cx, rval);
|
||||
if (!fun)
|
||||
return;
|
||||
|
||||
/* oh, for local roots */
|
||||
JS_AddRoot(cx, &cdatastr);
|
||||
|
||||
cdatastr = JS_NewStringCopyZ(cx, s);
|
||||
if (!cdatastr)
|
||||
goto out;
|
||||
argv[0] = STRING_TO_JSVAL(cdatastr);
|
||||
JS_CallFunction(cx, cb->obj, fun, 1, argv, &rval);
|
||||
|
||||
out:
|
||||
JS_RemoveRoot(cx, &cdatastr);
|
||||
}
|
||||
|
||||
static void
|
||||
ProcessingInstructionHandler(void *userdata, const char *target,
|
||||
const char *data)
|
||||
{
|
||||
XMLCallback *cb = (XMLCallback *)userdata;
|
||||
JSString *targetstr = NULL, *datastr = NULL;
|
||||
JSContext *cx = cb->cx;
|
||||
jsval argv[2];
|
||||
jsval rval;
|
||||
JSFunction *fun;
|
||||
|
||||
if (!JS_GetProperty(cx, cb->obj, "processingInstruction", &rval) ||
|
||||
JSVAL_IS_VOID(rval) || JSVAL_IS_NULL(rval))
|
||||
return;
|
||||
|
||||
fun = JS_ValueToFunction(cx, rval);
|
||||
if (!fun)
|
||||
return;
|
||||
JS_AddRoot(cx, &targetstr);
|
||||
JS_AddRoot(cx, &datastr);
|
||||
targetstr = JS_NewStringCopyZ(cx, target);
|
||||
if (!targetstr)
|
||||
goto out;
|
||||
datastr = JS_NewStringCopyZ(cx, data);
|
||||
if (!datastr)
|
||||
goto out;
|
||||
argv[0] = STRING_TO_JSVAL(targetstr);
|
||||
argv[1] = STRING_TO_JSVAL(datastr);
|
||||
JS_CallFunction(cx, cb->obj, fun, 2, argv, &rval);
|
||||
|
||||
out:
|
||||
JS_RemoveRoot(cx, &targetstr);
|
||||
JS_RemoveRoot(cx, &datastr);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
XMLParser(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
XMLCallback *cb = JS_malloc(cx, sizeof(XMLCallback));
|
||||
if (!cb)
|
||||
return JS_FALSE;
|
||||
cb->start = StartElementHandler;
|
||||
cb->end = EndElementHandler;
|
||||
cb->cdata = CharacterDataHandler;
|
||||
cb->processing = ProcessingInstructionHandler;
|
||||
cb->xml = NULL;
|
||||
cb->obj = obj;
|
||||
cb->preParse = cb->postParse = NULL;
|
||||
cb->cx = cx; /* XXX obj can persist longer than cx *sigh* */
|
||||
return JS_SetPrivate(cx, obj, (void *)cb);
|
||||
}
|
||||
|
||||
static void
|
||||
xmlparser_finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
XMLCallback *cb;
|
||||
|
||||
cb = (XMLCallback *)JS_GetPrivate(cx, obj);
|
||||
if (!cb)
|
||||
return;
|
||||
JS_free(cx, cb);
|
||||
}
|
||||
|
||||
JSClass XMLParser_class = {
|
||||
"XMLParser", JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, xmlparser_finalize
|
||||
};
|
||||
|
||||
JSFunctionSpec xmlparser_funcs[] = {
|
||||
{0}
|
||||
};
|
||||
|
||||
JSPropertySpec xmlparser_props[] = {
|
||||
{0}
|
||||
};
|
||||
|
||||
JSBool
|
||||
XMLParser_Init(JSContext *cx, JSObject *obj, JSObject *parent_proto)
|
||||
{
|
||||
JSObject *proto = JS_InitClass(cx, obj, parent_proto, &XMLParser_class,
|
||||
XMLParser, 1,
|
||||
xmlparser_props, xmlparser_funcs,
|
||||
NULL, NULL);
|
||||
return proto &&
|
||||
JS_DefineProperty(cx, proto, "startElement", JSVAL_NULL, NULL, NULL,
|
||||
JSPROP_ENUMERATE) &&
|
||||
JS_DefineProperty(cx, proto, "endElement", JSVAL_NULL, NULL, NULL,
|
||||
JSPROP_ENUMERATE) &&
|
||||
JS_DefineProperty(cx, proto, "characterData", JSVAL_NULL, NULL, NULL,
|
||||
JSPROP_ENUMERATE) &&
|
||||
JS_DefineProperty(cx, proto, "processingInstruction", JSVAL_NULL,
|
||||
NULL, NULL, JSPROP_ENUMERATE);
|
||||
}
|
||||
38
mozilla/modules/xml/js/test/Makefile
Normal file
38
mozilla/modules/xml/js/test/Makefile
Normal file
@@ -0,0 +1,38 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH = ../../../..
|
||||
REQUIRES = xmlparse xmltok expat js xmljs nspr
|
||||
CSRCS = js.c \
|
||||
$(NULL)
|
||||
|
||||
PROGRAM = xmljs
|
||||
|
||||
include $(DEPTH)/config/rules.mk
|
||||
CFLAGS += -DJSFILE -I.
|
||||
|
||||
MYLIBS = -lxmljs -lexpat -lxmltok -ljs $(LIBNSPR) -ldl -lm
|
||||
|
||||
js:
|
||||
rm -f $(PROGRAM)
|
||||
@make $(PROGRAM)
|
||||
|
||||
$(PROGRAM): $(OBJS)
|
||||
@$(MAKE_OBJDIR)
|
||||
$(CC) -o $@ $(LDFLAGS) $(OBJS) -L$(DIST)/bin $(MYLIBS)
|
||||
|
||||
|
||||
1265
mozilla/modules/xml/js/test/js.c
Normal file
1265
mozilla/modules/xml/js/test/js.c
Normal file
File diff suppressed because it is too large
Load Diff
41
mozilla/modules/xml/js/test/jsstddef.h
Normal file
41
mozilla/modules/xml/js/test/jsstddef.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*stddef inclusion here to first declare ptrdif as a signed long instead of a signed int*/
|
||||
|
||||
#ifdef _WINDOWS
|
||||
# ifndef XP_WIN
|
||||
# define XP_WIN
|
||||
# endif
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
# ifndef XP_WIN32
|
||||
# define XP_WIN32
|
||||
# endif
|
||||
#else
|
||||
# ifndef XP_WIN16
|
||||
# define XP_WIN16
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN16
|
||||
#ifndef _PTRDIFF_T_DEFINED
|
||||
typedef long ptrdiff_t;
|
||||
|
||||
/*
|
||||
* The Win16 compiler treats pointer differences as 16-bit signed values.
|
||||
* This macro allows us to treat them as 17-bit signed values, stored in
|
||||
* a 32-bit type.
|
||||
*/
|
||||
#define PTRDIFF(p1, p2, type) \
|
||||
((((unsigned long)(p1)) - ((unsigned long)(p2))) / sizeof(type))
|
||||
|
||||
#define _PTRDIFF_T_DEFINED
|
||||
#endif /*_PTRDIFF_T_DEFINED*/
|
||||
#else /*WIN16*/
|
||||
|
||||
#define PTRDIFF(p1, p2, type) \
|
||||
((p1) - (p2))
|
||||
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
54
mozilla/modules/xml/js/test/moz.rdf
Normal file
54
mozilla/modules/xml/js/test/moz.rdf
Normal file
@@ -0,0 +1,54 @@
|
||||
|
||||
<RDF:RDF>
|
||||
|
||||
<Topic id="root" name="Mozilla.Org">
|
||||
<child href="http://www.mozilla.org/mission.html" name="Our Mission"/>
|
||||
<child>
|
||||
<Topic id="WhoWeAre" name="Who We Are">
|
||||
<child href="http://www.mozilla.org/about.html" name="About Us"/>
|
||||
<child>
|
||||
<Topic id="FAQ" name="FAQ">
|
||||
<child href="http://www.mozilla.org/faq.html" name="FAQs"/>
|
||||
<child href="http://www.mozilla.org/free-faq.html" name="Free Navigator FAQ"/>
|
||||
<child href="http://www.mozilla.org/src-faq.html" name="Open Source FAQ"/>
|
||||
<child href="http://home.netscape.com/newsref/pr/newsrelease577.html"
|
||||
name="Press Release"/>
|
||||
</Topic>
|
||||
</child>
|
||||
</Topic>
|
||||
</child>
|
||||
<child href="http://www.mozilla.org/news.html" name="News"/>
|
||||
<child href="http://www.mozilla.org/community.html" name="Community"/>
|
||||
<child href="http://www.mozilla.org/get-involved.html" name="Get Involved"/>
|
||||
<child href="http://www.mozilla.org/projects.html" name="Projects"/>
|
||||
<child href="http://www.mozilla.org/blue-sky.html" name="Blue Sky"/>
|
||||
<child href="http://www.mozilla.org/advocacy.html" name="Advocacy"/>
|
||||
|
||||
<child>
|
||||
<Topic id="DC" name="Documentation">
|
||||
<child href="http://www.mozilla.org/docs.html" name="Documentation"/>
|
||||
<child href="http://www.mozilla.org/library.html" name="Library"/>
|
||||
</Topic>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<Topic id="dl" name="Downloads">
|
||||
<child href="http://www.mozilla.org/download.html" name="Downloads"/>
|
||||
<child href="http://www.mozilla.org/mirrors.html" name="Mirrors"/>
|
||||
</Topic>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<Topic id="bg" name="Bugs">
|
||||
<child href="http://www.mozilla.org/report.html" name="Reporting Bugs"/>
|
||||
<child href="http://www.mozilla.org/bugs.html" name="Bug Database"/>
|
||||
</Topic>
|
||||
</child>
|
||||
|
||||
<child href="http://www.mozilla.org/search" name="Search"/>
|
||||
<child href="http://www.mozilla.org/feedback.html" name="Feedback"/>
|
||||
<child href="http://developer.netscape.com/index_moz.html" name="DevEdge"/>
|
||||
|
||||
</Topic>
|
||||
|
||||
</RDF:RDF>
|
||||
64
mozilla/modules/xml/js/test/navcntr.rdf
Normal file
64
mozilla/modules/xml/js/test/navcntr.rdf
Normal file
@@ -0,0 +1,64 @@
|
||||
|
||||
|
||||
<RDF:RDF>
|
||||
|
||||
<Topic id="NC:NavCenter">
|
||||
<child>
|
||||
<Topic id="NC:Bookmarks" name="Bookmarks"/>
|
||||
</child>
|
||||
|
||||
<child href="NC:Search" largeIcon="icon/large:workspace,search" name="Srch"/>
|
||||
|
||||
<child>
|
||||
<Topic id="NC:History" largeIcon="icon/large:workspace,history" name="History" />
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<Topic id="NC:Sitemaps" name="Site Tools" htmlURL="http://rdf.netscape.com/rdf/navcntradvert.html" />
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<Topic id="NC:LocalFiles" name="Files" largeIcon="http://rdf.netscape.com/rdf/heabou.gif"/>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<Topic id="http://www.netscape.com/netcenter.rdf#root" name="Netcenter"/>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<Topic id="http://www.ilrt.bris.ac.uk/discovery/demos/rdf/webcat.rdf#ilrtroot" name="WebCat"/>
|
||||
<child>
|
||||
|
||||
<child>
|
||||
<Topic id="NC:NavInternals" name="Navigator Internals">
|
||||
<child href="NC:SmartBrowsingProviders" name="SmartBrowsing Providers"/>
|
||||
</Topic>
|
||||
</child>
|
||||
|
||||
</Topic>
|
||||
|
||||
<Topic id="NC:SmartBrowsingProviders">
|
||||
<child href="http://altavista.digital.com/cgi-bin/query?q=link%3A"
|
||||
name="Who points to me?"
|
||||
resultType="TEXT/HTML"/>
|
||||
<child href="http://www-rl1.netscape.com/wtgn?" name="Related Links"
|
||||
resultType="TEXT/RDF" />
|
||||
</Topic>
|
||||
|
||||
</RDF:RDF>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
13
mozilla/modules/xml/js/test/test.xml
Normal file
13
mozilla/modules/xml/js/test/test.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<toplevel>
|
||||
<child id="foo">
|
||||
<one/>
|
||||
<two/>
|
||||
<three/>
|
||||
</child>
|
||||
<child id="baz"/>
|
||||
<child id="bar">
|
||||
<four/>
|
||||
<five/>
|
||||
<six/>
|
||||
</child>
|
||||
</toplevel>
|
||||
23
mozilla/modules/xml/js/test/xmlgraph.js
Normal file
23
mozilla/modules/xml/js/test/xmlgraph.js
Normal file
@@ -0,0 +1,23 @@
|
||||
prefix = "";
|
||||
|
||||
xml = new XMLGraph();
|
||||
xml.parseFile("moz.rdf");
|
||||
|
||||
function dumpobj(o, name) {
|
||||
print(prefix + "dumping " + name);
|
||||
prefix += " ";
|
||||
if (typeof(o) != "object") {
|
||||
print(prefix + typeof(o) + " " + o + " is not an object!\n");
|
||||
return;
|
||||
}
|
||||
for (i in o) {
|
||||
if (typeof(o[i]) == "object")
|
||||
dumpobj(o[i], i);
|
||||
else
|
||||
print(prefix + i + "=" + o[i]);
|
||||
}
|
||||
prefix = prefix.substring(2);
|
||||
print(prefix + "done " + name);
|
||||
}
|
||||
|
||||
dumpobj(xml.graph, "RDF:RDF");
|
||||
29
mozilla/modules/xml/js/test/xmlparse.js
Normal file
29
mozilla/modules/xml/js/test/xmlparse.js
Normal file
@@ -0,0 +1,29 @@
|
||||
prefix = "";
|
||||
|
||||
function startElement(name, attr) {
|
||||
print(prefix + 'starting "' + name + '"')
|
||||
prefix += " ";
|
||||
for (i in attr) {
|
||||
print(prefix + i + '=' + attr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function endElement(name) {
|
||||
prefix = prefix.substring(2);
|
||||
print(prefix + 'ending "' + name + '"');
|
||||
}
|
||||
|
||||
function characterData(cdata) {
|
||||
print(prefix + 'CDATA: "' + cdata + '"');
|
||||
}
|
||||
|
||||
function processingInstruction(target, data) {
|
||||
print(prefix + 'processing insn for "' + target + '": "' + data + '"');
|
||||
}
|
||||
|
||||
xml = new XMLParser();
|
||||
xml.startElement = startElement;
|
||||
xml.endElement = endElement;
|
||||
xml.characterData = null; // characterData;
|
||||
|
||||
xml.parseFile("moz.rdf");
|
||||
147
mozilla/modules/xml/js/xmljs.c
Normal file
147
mozilla/modules/xml/js/xmljs.c
Normal file
@@ -0,0 +1,147 @@
|
||||
#define XMLJS_INTERNAL
|
||||
#include "xmljs.h"
|
||||
#undef XMLJS_INTERNAL
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/**
|
||||
* Parse a given string of XML.
|
||||
* If we fail, we (try to) set an error property on the given obj, and
|
||||
* return JSVAL_FALSE.
|
||||
* If all is well, we return JSVAL_TRUE.
|
||||
*/
|
||||
|
||||
JSBool
|
||||
xmljs_parse(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
XMLCallback *cb;
|
||||
XML_Parser xml;
|
||||
JSString *str;
|
||||
JSBool ok;
|
||||
|
||||
cb = (XMLCallback *)JS_GetPrivate(cx, obj);
|
||||
if (!cb) {
|
||||
JS_ReportError(cx, "XMLParser object has no parser!");
|
||||
return JS_FALSE;
|
||||
}
|
||||
if (cb->preParse &&
|
||||
!cb->preParse(cx, obj, argc, argv, rval))
|
||||
return JS_FALSE;
|
||||
if (argc < 1) {
|
||||
*rval = JSVAL_TRUE;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
xml = XML_ParserCreate(NULL);
|
||||
if (!xml)
|
||||
return JS_FALSE; /* XXX report error */
|
||||
/* after this point, have to leave via out: */
|
||||
|
||||
XML_SetElementHandler(xml, cb->start, cb->end);
|
||||
XML_SetCharacterDataHandler(xml, cb->cdata);
|
||||
XML_SetProcessingInstructionHandler(xml, cb->processing);
|
||||
XML_SetUserData(xml, (void *)cb);
|
||||
cb->xml = xml;
|
||||
str = JS_ValueToString(cx, argv[0]);
|
||||
if (!XML_Parse(xml, JS_GetStringBytes(str), JS_GetStringLength(str), 1)) {
|
||||
str = JS_NewStringCopyZ(cx, XML_ErrorString(XML_GetErrorCode(xml)));
|
||||
if (!str) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
if (!JS_DefineProperty(cx, obj, "error", STRING_TO_JSVAL(str),
|
||||
NULL, NULL, JSPROP_ENUMERATE)) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
*rval = JSVAL_FALSE;
|
||||
} else {
|
||||
*rval = JSVAL_TRUE;
|
||||
}
|
||||
out:
|
||||
XML_ParserFree(xml);
|
||||
cb->xml = NULL;
|
||||
return ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a file into a string and call the above.
|
||||
* XXX when File object is present, we don't need this mess.
|
||||
*/
|
||||
|
||||
static JSBool
|
||||
xmljs_parseFile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
jsval *rval)
|
||||
{
|
||||
JSString *str, *filename;
|
||||
struct stat sbuf;
|
||||
char * buf;
|
||||
int fd, len;
|
||||
|
||||
*rval = JSVAL_TRUE;
|
||||
if (argc < 1)
|
||||
return JS_TRUE;
|
||||
filename = JS_ValueToString(cx, argv[0]);
|
||||
if (!filename)
|
||||
return JS_TRUE;
|
||||
|
||||
argv[0] = STRING_TO_JSVAL(filename);
|
||||
|
||||
fd = open(JS_GetStringBytes(filename), O_RDONLY);
|
||||
if (fd < 0) {
|
||||
JS_ReportError(cx,
|
||||
"XMLParser.prototype.parseFile: open of %s failed!\n",
|
||||
JS_GetStringBytes(filename));
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if (fstat(fd, &sbuf) < 0) {
|
||||
JS_ReportError(cx,
|
||||
"XMLParser.prototype.parseFile: stat of %s failed!\n",
|
||||
JS_GetStringBytes(filename));
|
||||
close(fd);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
len = sbuf.st_size;
|
||||
buf = (char *)JS_malloc(cx, len);
|
||||
if (read(fd, (void *)buf, (size_t)len) < len) {
|
||||
JS_ReportError(cx,
|
||||
"XMLParser.prototype.parseFile: read of %s failed!\n",
|
||||
JS_GetStringBytes(filename));
|
||||
JS_free(cx, buf);
|
||||
close(fd);
|
||||
return JS_FALSE;
|
||||
}
|
||||
close(fd);
|
||||
str = JS_NewString(cx, buf, len); /* hand buf off to engine; don't free! */
|
||||
if (!str) {
|
||||
JS_free(cx, buf);
|
||||
return JS_FALSE;
|
||||
}
|
||||
argv[0] = STRING_TO_JSVAL(str);
|
||||
return JS_CallFunctionName(cx, obj, "parse", argc, argv, rval);
|
||||
}
|
||||
|
||||
JSBool
|
||||
XML_Init(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
jsval rval;
|
||||
JSObject *proto;
|
||||
|
||||
if (!JS_EvaluateScript(cx, JS_GetGlobalObject(cx), xmljs_newObj_str,
|
||||
xmljs_newObj_size,
|
||||
"XMLJS internal", 0, &rval))
|
||||
return JS_FALSE;
|
||||
|
||||
proto = JSVAL_TO_OBJECT(rval);
|
||||
if (!JS_DefineFunction(cx, proto, "parse", xmljs_parse,
|
||||
1, 0) ||
|
||||
!JS_DefineFunction(cx, proto, "parseFile", xmljs_parseFile,
|
||||
1, 0))
|
||||
return JS_FALSE;
|
||||
|
||||
return XMLParser_Init(cx, obj, proto) && XMLGraph_Init(cx, obj, proto);
|
||||
}
|
||||
34
mozilla/modules/xml/js/xmljs.h
Normal file
34
mozilla/modules/xml/js/xmljs.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef XMLJS_H
|
||||
#define XMLJS_H
|
||||
|
||||
#include <xmlparse.h>
|
||||
#include <jsapi.h>
|
||||
|
||||
extern JSBool
|
||||
XML_Init(JSContext *cx, JSObject *obj);
|
||||
|
||||
#ifdef XMLJS_INTERNAL
|
||||
typedef struct {
|
||||
JSContext *cx;
|
||||
JSObject *obj;
|
||||
XML_Parser xml;
|
||||
XML_StartElementHandler start;
|
||||
XML_EndElementHandler end;
|
||||
XML_CharacterDataHandler cdata;
|
||||
XML_ProcessingInstructionHandler processing;
|
||||
JSNative preParse;
|
||||
JSNative postParse;
|
||||
} XMLCallback;
|
||||
|
||||
extern JSBool
|
||||
XMLParser_Init(JSContext *cx, JSObject *obj, JSObject *parent_proto);
|
||||
|
||||
extern JSBool
|
||||
XMLGraph_Init(JSContext *cx, JSObject *obj, JSObject *parent_proto);
|
||||
|
||||
#define xmljs_newObj_str "new Object();"
|
||||
#define xmljs_newObj_size (sizeof(xmljs_newObj_str) - 1)
|
||||
|
||||
#endif /* XMLJS_INTERNAL */
|
||||
|
||||
#endif /* XMLJS_H */
|
||||
Reference in New Issue
Block a user