📄 dom_smjs.c
字号:
GF_Node *n; char *name; if (!JS_InstanceOf(c, obj, &dom_rt->domElementClass, NULL) ) return JS_FALSE; if (!argc || !JSVAL_IS_STRING(argv[0])) return JS_FALSE; n = dom_get_node(c, obj, NULL); name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); /*NS version*/ if (argc==2) { if (!JSVAL_IS_STRING(argv[1])) return JS_FALSE; name = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); } if (!name) return JS_FALSE; tag = TAG_DOM_ATTRIBUTE_FULL; node = (GF_DOMFullNode*)n; prev = NULL; att = (GF_DOMFullAttribute*)node->attributes; if (n->sgprivate->tag==TAG_DOMFullNode) tag = TAG_DOM_ATTRIBUTE_FULL; else if (n->sgprivate->tag<=GF_NODE_RANGE_LAST_SVG) tag = gf_svg_get_attribute_tag(n->sgprivate->tag, name); while (att) { if ((att->tag==TAG_DOM_ATTRIBUTE_FULL) && !strcmp(att->name, name)) { if (prev) prev->next = att->next; else node->attributes = att->next; if (att->data) free(att->data); free(att->name); free(att); dom_node_changed(n, 0, NULL); return JS_TRUE; } else if (tag==att->tag) { if (prev) prev->next = att->next; else node->attributes = att->next; gf_svg_delete_attribute_value(att->data_type, att->data, n->sgprivate->scenegraph); free(att); dom_node_changed(n, 0, NULL); return JS_TRUE; } prev = att; att = (GF_DOMFullAttribute *) att->next; } return JS_TRUE;}static JSBool xml_element_set_attribute(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ u32 evtType; GF_Node *n; char *name, *val; if (!JS_InstanceOf(c, obj, &dom_rt->domElementClass, NULL) ) return JS_FALSE; if ((argc < 2) || !JSVAL_IS_STRING(argv[0]) ) return JS_FALSE; n = dom_get_node(c, obj, NULL); name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); /*may not be a string in DOM*/ val = JS_GetStringBytes(JS_ValueToString(c, argv[1])); /*NS version*/ if (argc==3) { name = val; val = JS_GetStringBytes(JS_ValueToString(c, argv[2])); } if (!name || !val) return JS_FALSE; if ((name[0]=='o') && (name[1]=='n')) { evtType = gf_dom_event_type_by_name(name + 2); if (evtType != GF_EVENT_UNKNOWN) { /*check if we're modifying an existing listener*/ SVG_handlerElement *handler; u32 i, count = (n->sgprivate->interact && n->sgprivate->interact->events) ? gf_list_count(n->sgprivate->interact->events) : 0; for (i=0;i<count; i++) { GF_FieldInfo info; GF_DOMText *text; GF_Node *listen = gf_list_get(n->sgprivate->interact->events, i); gf_svg_get_attribute_by_tag(listen, TAG_SVG_ATT_event, 0, 0, &info); if (!info.far_ptr || (((XMLEV_Event*)info.far_ptr)->type != evtType)) continue; gf_svg_get_attribute_by_tag(listen, TAG_SVG_ATT_handler, 0, 0, &info); assert(info.far_ptr); handler = (SVG_handlerElement *) ((XMLRI*)info.far_ptr)->target; text = (GF_DOMText*)handler->children->node; if (text->sgprivate->tag==TAG_DOMText) { if (text->textContent) free(text->textContent); text->textContent = strdup(val); } return JS_TRUE; } /*nope, create a listener*/ handler = gf_dom_listener_build(n, evtType, 0, NULL); gf_dom_add_text_node((GF_Node*)handler, strdup(val) ); return JS_TRUE; } } if (n->sgprivate->tag==TAG_DOMFullNode) { GF_DOMFullAttribute *prev = NULL; GF_DOMFullNode *node = (GF_DOMFullNode*)n; GF_DOMFullAttribute *att = (GF_DOMFullAttribute*)node->attributes; while (att) { if ((att->tag==TAG_DOM_ATTRIBUTE_FULL) && !strcmp(att->name, name)) { if (att->data) free(att->data); att->data = strdup(val); dom_node_changed(n, 0, NULL); return JS_TRUE; } prev = att; att = (GF_DOMFullAttribute *) att->next; } /*create new att*/ GF_SAFEALLOC(att, GF_DOMFullAttribute); att->name = strdup(name); att->data = strdup(val); if (prev) prev->next = (GF_DOMAttribute*) att; else node->attributes = (GF_DOMAttribute*) att; return JS_TRUE; } if (n->sgprivate->tag<=GF_NODE_RANGE_LAST_SVG) { GF_FieldInfo info; if (gf_svg_get_attribute_by_name(n, name, 1, 1, &info)==GF_OK) { gf_svg_parse_attribute(n, &info, val, 0); dom_node_changed(n, 0, &info); return JS_TRUE; } } return JS_TRUE;}static JSBool xml_element_elements_by_tag(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ DOMNodeList *nl; GF_Node *n; JSObject *new_obj; char *name; if (!JS_InstanceOf(c, obj, &dom_rt->domElementClass, NULL) ) return JS_FALSE; if (!argc || !JSVAL_IS_STRING(argv[0])) return JS_FALSE; n = dom_get_node(c, obj, NULL); if (!n) return JS_FALSE; name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); /*NS version*/ if (argc==2) { if (!JSVAL_IS_STRING(argv[1])) return JS_FALSE; name = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); } GF_SAFEALLOC(nl, DOMNodeList); if (name && !strcmp(name, "*")) name = NULL; xml_doc_gather_nodes((GF_ParentNode*)n, name, nl); new_obj = JS_NewObject(c, &dom_rt->domNodeListClass, 0, 0); JS_SetPrivate(c, new_obj, nl); *rval = OBJECT_TO_JSVAL(new_obj); return JS_TRUE;}static JSBool xml_element_set_id(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ GF_Node *n; const char *node_name; u32 node_id; char *name; Bool is_id; if (!JS_InstanceOf(c, obj, &dom_rt->domElementClass, NULL) ) return JS_FALSE; if ((argc<2) || !JSVAL_IS_STRING(argv[0])) return JS_FALSE; n = dom_get_node(c, obj, NULL); if (!n) return JS_FALSE; name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); /*NS version*/ if (argc==2) { if (!JSVAL_IS_STRING(argv[1])) return JS_FALSE; name = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); is_id = (JSVAL_TO_BOOLEAN(argv[2])==JS_TRUE) ? 1 : 0; } else { is_id = (JSVAL_TO_BOOLEAN(argv[1])==JS_TRUE) ? 1 : 0; } node_name = gf_node_get_name_and_id(n, &node_id); if (node_id && is_id) { /*we only support ONE ID per node*/ return JS_FALSE; } if (is_id) { if (!name) return JS_FALSE; gf_node_set_id(n, gf_sg_get_max_node_id(n->sgprivate->scenegraph) + 1, strdup(name) ); } else if (node_id) { gf_node_remove_id(n); } return JS_TRUE;}/*dom3 character/text/comment*/static JSBool dom_text_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp){ GF_DOMText *txt; u32 prop_id; if (!JS_InstanceOf(c, obj, &dom_rt->domTextClass, NULL)) return JS_FALSE; if (!JSVAL_IS_INT(id)) return JS_TRUE; prop_id = JSVAL_TO_INT(id); if (prop_id<=JS_DOM3_NODE_LAST_PROP) return dom_node_getProperty(c, obj, id, vp); txt = (GF_DOMText*)dom_get_node(c, obj, NULL); if (!txt) return JS_FALSE; switch (prop_id) { /*"data"*/ case JS_DOM3_NODE_LAST_PROP+1: if (txt->textContent) *vp = STRING_TO_JSVAL( JS_NewStringCopyZ(c, txt->textContent ) ); else *vp = STRING_TO_JSVAL( JS_NewStringCopyZ(c, "") ); return JS_TRUE; /*"length"*/ case JS_DOM3_NODE_LAST_PROP+2: *vp = INT_TO_JSVAL(txt->textContent ? strlen(txt->textContent) : 0); return JS_TRUE; /*"isElementContentWhitespace"*/ case JS_DOM3_NODE_LAST_PROP+3: *vp = BOOLEAN_TO_JSVAL(JS_FALSE); return JS_TRUE; /*"wholeText"*/ case JS_DOM3_NODE_LAST_PROP+4: /*FIXME - this is wrong*/ *vp = INT_TO_JSVAL(txt->textContent ? strlen(txt->textContent) : 0); return JS_TRUE; } return JS_FALSE;}static JSBool dom_text_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp){ GF_DOMText *txt; u32 prop_id; if (!JS_InstanceOf(c, obj, &dom_rt->domTextClass, NULL)) return JS_FALSE; if (!JSVAL_IS_INT(id)) return JS_TRUE; prop_id = JSVAL_TO_INT(id); if (prop_id<=JS_DOM3_NODE_LAST_PROP) return dom_node_setProperty(c, obj, id, vp); txt = (GF_DOMText*)dom_get_node(c, obj, NULL); if (!txt) return JS_FALSE; switch (prop_id) { /*"data"*/ case JS_DOM3_NODE_LAST_PROP+1: if (txt->textContent) free(txt->textContent); txt->textContent = NULL; if (JSVAL_IS_STRING(*vp)) { txt->textContent = strdup( JS_GetStringBytes(JSVAL_TO_STRING(*vp)) ); } dom_node_changed((GF_Node*)txt, 0, NULL); return JS_TRUE; /*the rest is read-only*/ } return JS_FALSE;}static JSBool event_stop_propagation(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ GF_DOM_Event *evt = JS_GetPrivate(c, obj); if (!evt) return JS_FALSE; evt->event_phase = 3; return JS_TRUE;}static JSBool event_prevent_default(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ GF_DOM_Event *evt = JS_GetPrivate(c, obj); if (!evt) return JS_FALSE; evt->event_phase = 4; return JS_TRUE;}static JSBool event_is_default_prevented(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ GF_DOM_Event *evt = JS_GetPrivate(c, obj); if (!evt) return JS_FALSE; *rval = (evt->event_phase == 4) ? JS_TRUE : JS_FALSE; return JS_TRUE;}static JSBool event_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp){ JSString *s; GF_DOM_Event *evt = JS_GetPrivate(c, obj); if (JSVAL_IS_INT(id)) { switch (JSVAL_TO_INT(id)) { /*type*/ case 0: s = JS_NewStringCopyZ(c, gf_dom_event_get_name(evt->type) ); *vp = STRING_TO_JSVAL( s ); break; /*target*/ case 1: *vp = dom_element_construct(c, evt->target); return JS_TRUE; /*currentTarget*/ case 2: *vp = dom_element_construct(c, evt->currentTarget); return JS_TRUE; /*namespaceURI*/ case 3: return JS_FALSE; /*bubbles*/ case 4: *vp = evt->bubbles ? JS_TRUE : JS_FALSE; return JS_TRUE; /*cancelable*/ case 5: *vp = evt->cancelable ? JS_TRUE : JS_FALSE; return JS_TRUE; /*screenX*/ case 7: *vp = INT_TO_JSVAL(evt->screenX); return JS_TRUE; /*screenY*/ case 8: *vp = INT_TO_JSVAL(evt->screenY); return JS_TRUE; /*clientX*/ case 9: *vp = INT_TO_JSVAL(evt->clientX); return JS_TRUE; /*clientY*/ case 10: *vp = INT_TO_JSVAL(evt->clientY); return JS_TRUE; /*button*/ case 11: *vp = INT_TO_JSVAL(evt->detail); return JS_TRUE; /*relatedTarget*/ case 12: *vp = dom_element_construct(c, evt->relatedTarget); return JS_TRUE; /*DOM3 event keyIndentifier*/ case 14: s = JS_NewStringCopyZ(c, gf_dom_get_key_name(evt->detail) ); *vp = STRING_TO_JSVAL( s ); return JS_TRUE; /*Mozilla keyChar, charCode: wrap up to same value*/ case 15: *vp = INT_TO_JSVAL(evt->detail); return JS_TRUE; /*zoomRectScreen*/ case 21: *vp = svg_udom_new_rect(c, evt->screen_rect.x, evt->screen_rect.y, evt->screen_rect.width, evt->screen_rect.height); return JS_TRUE; /*previousScale*/ case 22: *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, evt->prev_scale) ); return JS_TRUE; /*previousTranslate*/ case 23: *vp = svg_udom_new_point(c, evt->prev_translate.x, evt->prev_translate.y); return JS_TRUE; /*newScale*/ case 24: *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, evt->new_scale) ); return JS_TRUE; /*newTranslate*/ case 25: *vp = svg_udom_new_point(c, evt->new_translate.x, evt->new_translate.y); return JS_TRUE; default: return JS_FALSE; } } return JS_TRUE;}/************************************************************ * * xmlHttpRequest implementation * *************************************************************/typedef struct{ JSContext *c; JSObject *_this; JSFunction *onreadystatechange; u32 readyState; Bool async; /*header/header-val, terminated by NULL*/ char **headers; u32 cur_header; char **recv_headers; char *method, *url; GF_DownloadSession *sess; char *data; u32 size; GF_Err ret_code; u32 html_status; char *statusText; GF_SAXParser *sax; GF_List *node_stack; /*dom graph*/ GF_SceneGraph *document;} XMLHTTPContext;static void xml_http_append_send_header(XMLHTTPContext *ctx, char *hdr, char *val){ u32 nb_hdr = 0; if (!hdr) return; if (ctx->headers) { nb_hdr = 0; while (ctx->headers && ctx->headers[nb_hdr]) { if (stricmp(ctx->headers[nb_hdr], hdr)) { nb_hdr+=2; continue; } /*ignore these ones*/ if (!stricmp(hdr, "Accept-Charset") || !stricmp(hdr, "Accept-Encoding") || !stricmp(hdr, "Content-Length") || !stricmp(hdr, "Expect") || !stricmp(hdr, "Date") || !stricmp(hdr, "Host") || !stricmp(hdr, "Keep-Alive") || !stricmp(hdr, "Referer") || !stricmp(hdr, "TE") || !stricmp(hdr, "Trailer") || !stricmp(hdr, "Transfer-Encoding") || !stricmp(hdr, "Upgrade") ) { return; } /*replace content for these ones*/ if (!stricmp(hdr, "Authorization") || !stricmp(hdr, "Content-Base") || !stricmp(hdr, "Content-Location") || !stricmp(hdr, "Content-MD5") || !stricmp(hdr, "Content-Range") || !stricmp(hdr, "Content-Type") || !stricmp(hdr, "Content-Version") || !stricmp(hdr, "Delta-Base") || !stricmp(hdr, "Depth") || !stricmp(hdr, "Destination") || !stricmp(hdr, "ETag") || !stricmp(hdr, "From") || !stricmp(hdr, "If-Modified-Since") || !stricmp(hdr, "If-Range") || !stricmp(hdr, "If-Unmodified-Since") || !stricmp(hdr, "Max-Forwards") || !stricmp(hdr, "MIME-Version") || !stricmp(hdr, "Overwrite") || !stricmp(hdr, "Proxy-Authorization") || !stricmp(hdr, "SOAPAction") || !stricmp(hdr, "Timeout") ) { free(ctx->headers[nb_hdr+1]); ctx->headers[nb_hdr+1] = strdup(val); return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -