- Update Unix make goo to handle our new MOZILLA_CLIENT dependencies.

- Added TODO and STYLE_NOTES
- Added style data to DOM_Element
- Added GetCleanEntryData convenience function
- Added internal dom_SetElementAttribute with optional suppressing of callback
  invocation
- Added style init code
- Style support (everything)
- Fix text initialization thinko


git-svn-id: svn://10.0.0.236/trunk@11289 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
shaver%netscape.com
1998-09-28 22:51:50 +00:00
parent 9ec704b72f
commit af556e9173
11 changed files with 1276 additions and 125 deletions

View File

@@ -20,9 +20,16 @@ DEPTH = ../..
MODULE = dom
LIBRARY_NAME = dom
REQUIRES = js
REQUIRES = js dom
EXPORTS = dom.h
ifdef MOZILLA_CLIENT
REQUIRES += lay img layer util
# hack until PERIGNON takes over the world
REQUIRES += style
endif
EXPORTS = dom.h domstyle.h
CSRCS = domattr.c \
domcore.c \
@@ -34,3 +41,5 @@ CSRCS = domattr.c \
$(NULL)
include $(DEPTH)/config/rules.mk
DEFINES += -DDOM

View File

@@ -26,8 +26,14 @@ MODULE = dom
LIBRARY_NAME = dom
REQUIRES = js
#ifdef MOZILLA_CLIENT
REQUIRES += lay img layer util
EXPORTS = $(srcdir)/dom.h
# hack until PERIGNON takes over the world
REQUIRES += style
#endif
EXPORTS = $(srcdir)/dom.h $(srcdir)/domstyle.h
CSRCS = domattr.c \
domcore.c \
@@ -39,3 +45,5 @@ CSRCS = domattr.c \
$(NULL)
include $(topsrcdir)/config/rules.mk
DEFINES += -DDOM

View File

@@ -0,0 +1,65 @@
Notes on DOM style support, or: Everything you ever wanted to know
about Perignon, but managed to avoid asking.
Data Structures:
----------------
Style data is represented by sets of disjoint trees, rooted on the
innermost element type (simple selector). The sets are stored in a
hash table. It's easier to understand with a picture, so here goes.
Legend:
-- ``enclosing''
| ``sibling''
(=...) ``rule''
Style data:
H1 { color:blue }
H1 A { color:red }
H1 B A { color:green }
B A { color:purple }
A:link { color:orange }
.A { color:forclassA }
A -- B (=color:purple) -- H1 (=color:green)
| |
| H1 (=color:red)
|
A:link (=color:orange)
|
|
.A (=color:forclassA)
H1 (=color:blue)
Note that there are no rules on the ``A'' selector. If the only rule
in the sheet for ``A'' was the ``A:visited'' one, a dummy selector
would be added, since the hash table is keyed on the pseudo-less
selector.
Classes (".H1") and IDs ("#H1") are chained in the sibling list with
their like-named tags.
A selector can correspond to a tag, class or id, depending on the
value of the type field. If a class selector applies to the magic
``all'' class, it will have no extra field. Otherwise, the extra
field will be the tag selector. If a tag selector has an ID as well,
it will be found in the extra field.
JSSS:
-----
Perignon currently depends on JSSS to populate it, but someday I should
implement DOM_StyleParseRule for the heathens that just use CSS.
CSS2:
-----
I don't do CSS2 selectors yet. I don't yet know how much I care about
that, because I don't yet know what CSS2 selectors are. =)
Questions:
----------
- Do visited links get A:link properties as well? They don't appear to in
the current implementation, but to my mind they should (unless, of course,
such properties are overridden by A:visited rules).

27
mozilla/lib/libdom/TODO Normal file
View File

@@ -0,0 +1,27 @@
General:
- document.create*
- escape HTML entities (JS entities?) coming into the text functions
Style:
- add a CSS-parsing input API, or extract CSS->JS conversion from
libstyle
- DOM_StyleIsDirty/DOM_LockStyle/DOM_UnlockStyle to allow global
caching of style data during document layout without racing with
alterations from mocha thread.
Layout:
- make proper LO_Elements for table stuff (pollmann)
- stick the DOM_StyleGetElementProperty stuff in all the right places
(reflow?)
- make <HR> honour inherited style (colour, etc.)
libmocha:
- move destruction into LM_ReleaseDocument
- add destruction of style db
- look closely at the implicit pop stuff in DOM_HTMLPushNode
- wire up node reordering
- put single <HTML> element child on #document at creation (and never
pop it off)
XML:
- everything, really

View File

@@ -224,8 +224,9 @@ struct DOM_Element {
DOM_ElementOps *ops;
const char *tagName;
uintN nattrs;
DOM_AttributeEntry *attrs;
void *style; /* later, later... */
DOM_AttributeEntry *attrs;
char *styleClass;
char *styleID;
};
/*
@@ -235,7 +236,7 @@ struct DOM_Element {
DOM_Element *
DOM_NewElement(const char *tagName, DOM_ElementOps *eleops, char *name,
DOM_NodeOps *nodeops);
char *styleClass, char *styleID, DOM_NodeOps *nodeops);
JSObject *
DOM_NewElementObject(JSContext *cx, DOM_Element *element);
@@ -251,6 +252,12 @@ JSBool
DOM_SetElementAttribute(JSContext *cx, DOM_Element *element, const char *name,
const char *value);
typedef JSBool(*DOM_DataParser)(const char *str, uint32 *data, void *closure);
JSBool
DOM_GetCleanEntryData(JSContext *cx, DOM_AttributeEntry *entry,
DOM_DataParser parser, uint32 *data, void *closure);
/*
* Set the attributes from a pair of synchronized lists.
* (This is what PA_FetchAllNameValues provides, handily enough.)

View File

@@ -43,6 +43,10 @@ dom_NodeInit(JSContext *cx, JSObject *obj);
JSObject *
dom_ElementInit(JSContext *cx, JSObject *obj, JSObject *node_proto);
JSBool
dom_SetElementAttribute(JSContext *cx, DOM_Element *element, const char *name,
const char *value, JSBool runCallback);
JSObject *
dom_AttributeInit(JSContext *cx, JSObject *scope, JSObject *node_proto);

View File

@@ -25,12 +25,17 @@
JSBool
DOM_Init(JSContext *cx, JSObject *scope) {
JSObject *node, *cdata;
return (( node = dom_NodeInit(cx, scope)) &&
dom_AttributeInit(cx, scope, node) &&
dom_ElementInit(cx, scope, node) &&
( cdata = dom_CharacterDataInit(cx, scope, node)) &&
dom_TextInit(cx, scope, cdata) &&
dom_CommentInit(cx, scope, cdata));
JSBool ok = (( node = dom_NodeInit(cx, scope)) &&
dom_AttributeInit(cx, scope, node) &&
dom_ElementInit(cx, scope, node) &&
( cdata = dom_CharacterDataInit(cx, scope, node)) &&
dom_TextInit(cx, scope, cdata) &&
dom_CommentInit(cx, scope, cdata));
#ifdef PERIGNON
ok &= (dom_StyleSelectorInit(cx, scope) &&
dom_TagsObjectInit(cx, scope));
#endif
return ok;
}
static char *exception_names[] = {

View File

@@ -188,7 +188,7 @@ static JSFunctionSpec element_methods[] = {
DOM_Element *
DOM_NewElement(const char *tagName, DOM_ElementOps *eleops, char *name,
DOM_NodeOps *nodeops)
char *styleClass, char *styleID, DOM_NodeOps *nodeops)
{
DOM_Node *node;
DOM_Element *element = XP_NEW_ZAP(DOM_Element);
@@ -201,7 +201,10 @@ DOM_NewElement(const char *tagName, DOM_ElementOps *eleops, char *name,
node->ops = nodeops;
element->tagName = tagName;
element->styleClass = styleClass;
element->styleID = styleID;
element->ops = eleops;
return element;
}
@@ -290,7 +293,22 @@ DOM_GetElementAttribute(JSContext *cx, DOM_Element *element, const char *name,
return JS_TRUE;
}
static JSBool
JSBool
DOM_GetCleanEntryData(JSContext *cx, DOM_AttributeEntry *entry,
DOM_DataParser parser, uint32 *data, void *closure)
{
if (entry->dirty) {
uint32 newdata;
if (!parser(entry->value, &newdata, closure))
return JS_FALSE;
entry->data = newdata;
entry->dirty = JS_FALSE;
}
*data = entry->data;
return JS_TRUE;
}
static DOM_AttributeEntry *
AddAttribute(JSContext *cx, DOM_Element *element, const char *name,
const char *value)
{
@@ -299,29 +317,31 @@ AddAttribute(JSContext *cx, DOM_Element *element, const char *name,
if (!element->attrs) {
element->attrs = JS_malloc(cx, sizeof(DOM_AttributeEntry));
if (!element->attrs)
return JS_FALSE;
return NULL;
element->nattrs = 1;
} else {
element->attrs = XP_REALLOC(element->attrs,
(element->nattrs++) * sizeof(DOM_AttributeEntry));
if (!element->attrs)
return JS_FALSE;
return NULL;
}
entry = element->attrs + element->nattrs - 1;
entry->name = name;
entry->value = value;
return JS_TRUE;
return entry;
}
JSBool
DOM_SetElementAttribute(JSContext *cx, DOM_Element *element, const char *name,
const char *value)
dom_SetElementAttribute(JSContext *cx, DOM_Element *element, const char *name,
const char *value, JSBool runCallback)
{
DOM_AttributeEntry *entry;
if (!DOM_GetElementAttribute(cx, element, name, &entry))
return JS_FALSE;
if (!entry) {
if (!AddAttribute(cx, element, name, value))
entry = AddAttribute(cx, element, name, value);
if (!entry)
return JS_FALSE;
} else {
if (entry->value)
@@ -330,9 +350,18 @@ DOM_SetElementAttribute(JSContext *cx, DOM_Element *element, const char *name,
}
entry->dirty = JS_TRUE;
if (!runCallback)
return JS_TRUE;
return element->ops->setAttribute(cx, element, name, value);
}
JSBool
DOM_SetElementAttribute(JSContext *cx, DOM_Element *element, const char *name,
const char *value)
{
return dom_SetElementAttribute(cx, element, name, value, JS_TRUE);
}
static JSBool
Element(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *vp)
{

File diff suppressed because it is too large Load Diff

View File

@@ -17,8 +17,7 @@
*/
/*
* Style things for the DOM.
* Very purty. Makes it all go.
* Perignon: store style information in the DOM, using CSS-1 selectors.
*/
#include "jsapi.h"
@@ -40,11 +39,6 @@ typedef struct DOM_StyleRule DOM_StyleRule;
/* this may become int or something later, for speed */
typedef const char *DOM_StyleToken;
#define DOM_STYLE_PSEUDO_TAG (1 << 7)
#define DOM_SELECTOR_IS_PSEUDO(sel) ((sel) & DOM_STYLE_PSEUDO_TAG)
#define DOM_STYLE_SELECTOR_TYPE(sel) ((sel) & ~DOM_STYLE_PSEUDO_TAG)
#define DOM_PSEUDOIZE(sel) ((sel) | DOM_STYLE_PSEUDO_TAG)
enum {
SELECTOR_UNKNOWN = 0,
SELECTOR_ID,
@@ -53,19 +47,33 @@ enum {
};
struct DOM_StyleDatabase {
PLHashTable *ht; /* PRHash, from js/ref or nsprpub, depending? */
PLHashTable *ht;
};
DOM_StyleDatabase *
DOM_NewStyleDatabase(JSContext *cx);
void
DOM_DestroyStyleDatabase(JSContext *cx, DOM_StyleDatabase *db);
/*
* Find or create the StyleDatabase for the given JSContext.
* The embedder must provide an implementation, or #define MOZILLA_CLIENT
* to get the Mozilla-specific one which depends on MochaDecoder and
* MWContext and lo_TopState and stuff.
*/
DOM_StyleDatabase *
DOM_StyleDatabaseFromContext(JSContext *cx);
struct DOM_StyleSelector {
int8 type;
DOM_StyleToken selector;
DOM_StyleToken pseudo;
DOM_StyleToken extra;
DOM_StyleSelector *enclosing;
DOM_StyleSelector *sibling;
DOM_StyleRule *rules;
JSObject *mocha_object; /* reflection for this selector's rules */
};
/*
@@ -80,14 +88,25 @@ struct DOM_StyleSelector {
* Now find/create a selector for "CODE B":
* sel2 = DOM_StyleFindSelector(cx, db, sel, "CODE", NULL);
*
* And for "A:visited CODE B":
* sel3 = DOM_StyleFindSelector(cx, db, sel2, "A", "visited");
* And ".myclass CODE B":
* sel3 = DOM_StyleFindSelector(cx, db, sel2, ".myclass", NULL);
*/
DOM_StyleSelector *
DOM_StyleFindSelector(JSContext *cx, DOM_StyleDatabase *db,
DOM_StyleSelector *base, DOM_StyleToken enclosing,
DOM_StyleToken pseudo);
/*
* As above, but take type explicitly rather than parsing leading # or . for
* ID or class. For classes or extra is a tag or NULL. For tags, extra is an
* ID or NULL. (For ID, extra is ignored.)
*/
DOM_StyleSelector *
DOM_StyleFindSelectorFull(JSContext *cx, DOM_StyleDatabase *db,
DOM_StyleSelector *base, uint8 type,
DOM_StyleToken enclosing, DOM_StyleToken extra,
DOM_StyleToken pseudo);
struct DOM_StyleRule {
DOM_AttributeEntry entry;
int16 weight;
@@ -96,7 +115,7 @@ struct DOM_StyleRule {
/*
* Parses a style rule and adds it to the style database.
* If len is 0, rule is presumed to be NUL-terminated.
* If len is 0, rule is presumed to be NUL-terminated. (XXX NYI)
*
* Usage example:
*
@@ -119,6 +138,8 @@ DOM_StyleParseRule(JSContext *cx, DOM_StyleDatabase *db, const char *rule,
* enclosing Element is used for finding matches. The implementation is
* necessarily somewhat hairy. See domstyle.c for details.
*
* If db is NULL, DOM_StyleDatabaseFromContext is used to find it.
*
* Usage examples:
*
* Get the color for a section of text:
@@ -130,16 +151,38 @@ DOM_StyleParseRule(JSContext *cx, DOM_StyleDatabase *db, const char *rule,
JSBool
DOM_StyleGetProperty(JSContext *cx, DOM_StyleDatabase *db, DOM_Node *node,
DOM_StyleToken property, DOM_StyleToken psuedo,
DOM_AttributeEntry **entryp);
DOM_StyleToken property, DOM_AttributeEntry **entryp);
/*
* Get/set the pseudoclass for an element
*/
DOM_StyleToken
DOM_GetElementPseudo(JSContext *cx, DOM_Element *element);
JSBool
DOM_SetElementPseudo(JSContext *cx, DOM_Element *element,
DOM_StyleToken pseudo);
/*
* Add a property to the provided selector.
*
* DOM_StyleAddRule(cx, db, sel, "color", "blue");
*/
JSBool
DOM_AttributeEntry *
DOM_StyleAddRule(JSContext *cx, DOM_StyleDatabase *db, DOM_StyleSelector *sel,
DOM_StyleToken name, const char *value);
/*
* Resolve classes, tags, ids, contextual on the given object.
*/
JSBool
DOM_DocObjectResolveStyleProps(JSContext *cx, JSObject *obj, jsval id);
/*
* The contextual selector JS function: contextual("H1", "EM");
*/
JSBool
DOM_JSContextual(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval);
#endif /* DOM_STYLE_H */

View File

@@ -373,6 +373,7 @@ DOM_NewText(const char *data, int64 length, DOM_CDataOp notify,
LL_L2I(nbytes, length);
cdata = (DOM_CharacterData *)text;
cdata->len = length;
cdata->data = XP_ALLOC(nbytes);
cdata->notify = notify;
if (!cdata->data) {