Wired up DOM-node destruction after firing onUnload.

Added event guck for altering attributes (will be rewritten to do
poke-and-schedule).
Tentatively blocked out LM_ClearContextStream, which looks like dead code.
This commit is contained in:
shaver%netscape.com 1998-09-04 00:05:53 +00:00
Родитель c06c2aaffb
Коммит cc2a027580
4 изменённых файлов: 139 добавлений и 34 удалений

Просмотреть файл

@ -3074,7 +3074,7 @@ ET_TweakSpan(MWContext * context, void *name_rec, void *param_ptr,
MozillaEvent_TweakSpan * event;
event = PR_NEW(MozillaEvent_TweakSpan);
if (event == NULL)
return NULL;
return 0;
PR_InitEvent(&event->ce.event, context,
(PRHandleEventProc)et_HandleEvent_TweakSpan,
@ -3197,4 +3197,73 @@ ET_DOMReflow(MWContext *context, LO_Element *element, PRBool reflow,
return (int)et_PostEvent(&event->ce, FALSE);
}
/* alter attributes for a layout element */
typedef struct {
ETEvent ce;
TagType tagtype;
void *ele1;
void *ele2;
char *name;
char *value;
} MozillaEvent_DOMSetAttr;
/*
* Set the attributes, and all that.
*/
PR_STATIC_CALLBACK(int)
et_HandleEvent_DOMSetAttr(MozillaEvent_DOMSetAttr *e)
{
/* check that the doc_id is valid */
if(XP_DOCID(e->ce.context) != e->ce.doc_id)
return FALSE;
switch(e->tagtype) {
case P_TABLE_DATA:
LO_SetTableCellAttributes(e->ce.context, e->ele1, e->name, e->value);
break;
}
return TRUE;
}
PR_STATIC_CALLBACK(void)
et_DestroyEvent_DOMSetAttr(MozillaEvent_DOMSetAttr *event)
{
XP_FREE(event->name);
XP_FREEIF(event->value);
XP_FREE(event);
}
/*
* arguably, we should define enums or something so that we don't have to
* XP_STRCASECMP both in lm_DOMSetAttributes and in the various handler
* functions. Later...
*/
int
ET_DOMSetAttributes(MWContext *context, TagType tagtype, void *ele1,
void *ele2, const char *name, const char *value,
int32 doc_id)
{
MozillaEvent_DOMSetAttr *event;
event = PR_NEW(MozillaEvent_DOMSetAttr);
if (!event)
return 0;
PR_InitEvent(&event->ce.event, context,
(PRHandleEventProc)et_HandleEvent_DOMSetAttr,
(PRDestroyEventProc)et_DestroyEvent_DOMSetAttr);
event->ce.context = context;
event->ce.doc_id = doc_id;
event->tagtype = tagtype;
event->ele1 = ele1;
event->ele2 = ele2;
event->name = XP_STRDUP(name);
if (value)
event->value = XP_STRDUP(value);
/*
* we post this synchronously so that a subsequent getAttribute
* call will see the right value. We should really cache the value
* in the lm_dom.c code so that this isn't necessary, but for now...
*/
return (int)et_PostEvent(&event->ce, TRUE);
}
#endif

Просмотреть файл

@ -103,42 +103,71 @@ static JSBool
lm_DOMSetAttributes(JSContext *cx, DOM_Element *element, const char *name,
const char *value)
{
JSBool ok = JS_FALSE;
JSBool matched = JS_FALSE;
MochaDecoder *decoder;
MWContext *context;
DOM_HTMLElementPrivate *priv;
LO_Element *ele;
void *ele1, *ele2;
decoder = (MochaDecoder *)JS_GetPrivate(cx, JS_GetGlobalObject(cx));
context = decoder->window_context;
priv = (DOM_HTMLElementPrivate *)element->node.data;
switch(priv->tagtype) {
case P_TABLE_DATA: {
lo_TableCell *cell;
cell = (lo_TableCell *)priv->ele_start;
ele = (LO_Element *)cell;
if (!XP_STRCASECMP("valign", name)) {
/* tweak vert alignment */
} else if (!XP_STRCASECMP("halign", name)) {
/* tweak horiz alignment */
} else if (!XP_STRCASECMP("bgcolor", name)) {
/* tweak bgcolor */
case P_TABLE_DATA:
if (!XP_STRCASECMP("valign", name) ||
!XP_STRCASECMP("halign", name) ||
!XP_STRCASECMP("bgcolor", name)) {
ele1 = priv->ele_start;
matched = JS_TRUE;
}
ok = JS_TRUE;
}
default:
ok = JS_FALSE;
break;
default:;
}
if (ok)
ET_DOMReflow(context, ele, PR_TRUE, decoder->doc_id);
if (!matched) {
DOM_SignalException(cx, DOM_INVALID_NAME_ERR);
return JS_FALSE;
}
ET_DOMSetAttributes(context, priv->tagtype, ele1, ele2,
name, value, decoder->doc_id);
return JS_TRUE;
}
static void
lm_BreakLayoutNodeLinkRecurse(DOM_Node *node)
{
DOM_HTMLElementPrivate *priv;
if (node->type == NODE_TYPE_TEXT ||
node->type == NODE_TYPE_ELEMENT) {
priv = (DOM_HTMLElementPrivate *)node->data;
if (priv)
priv->ele_start = priv->ele_end = NULL;
}
for (node = node->child; node; node = node->sibling)
lm_BreakLayoutNodeLinkRecurse(node);
}
void
lm_DestroyDocumentNodes(MWContext *context)
{
JSContext *cx;
lo_TopState *top;
cx = context->mocha_context;
top = lo_FetchTopState(context->doc_id);
/* XXX LO_LockLayout(); */
lm_BreakLayoutNodeLinkRecurse(top->top_node);
/* XXX LO_UnlockLayout(); */
DOM_DestroyTree(cx, top->top_node);
return ok;
}
DOM_ElementOps lm_ElementOps = {
DOM_SetAttributeStub, DOM_GetAttributeStub, DOM_GetNumAttrsStub
lm_DOMSetAttributes, DOM_GetAttributeStub, DOM_GetNumAttrsStub
};
/*
@ -201,7 +230,6 @@ lm_NodeForTag(PA_Tag *tag, DOM_Node *current, MWContext *context, int16 csid)
DOM_Node *node;
DOM_Element *element;
DOM_HTMLElementPrivate *elepriv;
DOM_CharacterData *cdata;
if (current->type == NODE_TYPE_TEXT)
/*
@ -215,19 +243,10 @@ lm_NodeForTag(PA_Tag *tag, DOM_Node *current, MWContext *context, int16 csid)
if (current->type != NODE_TYPE_ELEMENT)
return NULL;
/* create Text node */
node = (DOM_Node *)XP_NEW_ZAP(DOM_Text);
node->type = NODE_TYPE_TEXT;
node->name = XP_STRDUP("#text");
node->ops = &lm_NodeOps;
cdata = (DOM_CharacterData *)node;
cdata->len = tag->data_len;
cdata->data = XP_ALLOC(tag->data_len);
cdata->notify = lm_CDataOp;
if (!cdata->data) {
XP_FREE(node);
node = (DOM_Node *)DOM_NewText((char *)tag->data, tag->data_len,
lm_CDataOp, &lm_NodeOps);
if (!node)
return NULL;
}
XP_MEMCPY(cdata->data, tag->data, cdata->len);
break;
#if 0 /* Urgh...we don't reflect comments! */
case P_COMMENT:

Просмотреть файл

@ -51,6 +51,9 @@ lm_DOMInitElement(MochaDecoder *decoder);
JSBool
lm_DOMInitAttribute(MochaDecoder *decoder);
void
lm_DestroyDocumentNodes(MWContext *context);
#endif /* DOM */
#endif /* LM_DOM_H */

Просмотреть файл

@ -21,6 +21,9 @@
* Brendan Eich, 9/8/95
*/
#include "lm.h"
#ifdef DOM
#include "lm_dom.h"
#endif
#include "xp.h"
#include "net.h"
#include "structs.h"
@ -1514,6 +1517,14 @@ lm_SendEvent(MWContext *context, JSObject *obj, JSEvent *event, jsval *result)
argv[0] = OBJECT_TO_JSVAL(eventObj);
ok = lm_FindEventHandler(context, obj, eventObj, funval, result);
#ifdef DOM
/* when firing the onUnload event, destroy the node tree afterwards */
if (event->type == EVENT_UNLOAD) {
/* XXX should we run GC before, to clean up reflections? */
lm_DestroyDocumentNodes(context);
}
#endif
out:
LM_PutMochaDecoder(decoder);
return ok;
@ -1860,6 +1871,8 @@ lm_ClearDecoderStream(MochaDecoder *decoder, JSBool fromDiscard)
return(stream);
}
#ifndef DOM
/* XXX believe that this is dead code, can I remove it? */
PRIVATE void
LM_ClearContextStream(MWContext *context)
{
@ -1878,6 +1891,7 @@ LM_ClearContextStream(MWContext *context)
lm_ClearDecoderStream(decoder, JS_FALSE);
LM_PutMochaDecoder(decoder);
}
#endif
JSBool
lm_SaveParamString(JSContext *cx, PA_Block *bp, const char *str)