diff options
Diffstat (limited to 'src/css')
-rw-r--r-- | src/css/cascade.nim | 84 | ||||
-rw-r--r-- | src/css/select.nim | 223 | ||||
-rw-r--r-- | src/css/stylednode.nim | 115 | ||||
-rw-r--r-- | src/css/values.nim | 2 |
4 files changed, 284 insertions, 140 deletions
diff --git a/src/css/cascade.nim b/src/css/cascade.nim index 8b93e8d0..25866ac0 100644 --- a/src/css/cascade.nim +++ b/src/css/cascade.nim @@ -21,9 +21,6 @@ type proc applyProperty(styledNode: StyledNode, parent: CSSComputedValues, d: CSSDeclaration) = styledNode.computed.applyValue(parent, d) - if styledNode.node != nil: - Element(styledNode.node).cssapplied = true - func applies(mq: MediaQuery): bool = case mq.t of CONDITION_MEDIA: @@ -59,16 +56,17 @@ func applies(mqlist: MediaQueryList): bool = type ToSorts = array[PseudoElem, seq[(int, seq[CSSDeclaration])]] -proc calcRule(tosorts: var ToSorts, elem: Element, rule: CSSRuleDef) = +proc calcRule(tosorts: var ToSorts, styledNode: StyledNode, rule: CSSRuleDef) = for sel in rule.sels: - if elem.selectorsMatch(sel): + if styledNode.selectorsMatch(sel): let spec = getSpecificity(sel) tosorts[sel.pseudo].add((spec,rule.decls)) -func calcRules(elem: Element, sheet: CSSStylesheet): DeclarationList = +func calcRules(styledNode: StyledNode, sheet: CSSStylesheet): DeclarationList = var tosorts: ToSorts + let elem = Element(styledNode.node) for rule in sheet.gen_rules(elem.tagType, elem.id, elem.classList): - tosorts.calcRule(elem, rule) + tosorts.calcRule(styledNode, rule) for i in PseudoElem: tosorts[i].sort((x, y) => cmp(x[0], y[0])) @@ -88,8 +86,7 @@ proc applyImportant(ares: var ApplyResult, decls: seq[CSSDeclaration]) = if decl.important: ares.important.add(decl) -# Always returns a new styled node, with the passed declarations applied. -proc applyDeclarations(elem: Element, parent: CSSComputedValues, ua, user: DeclarationList, author: seq[DeclarationList]): StyledNode = +proc applyDeclarations(styledNode: StyledNode, parent: CSSComputedValues, ua, user: DeclarationList, author: seq[DeclarationList]) = let pseudo = PSEUDO_NONE var ares: ApplyResult @@ -101,21 +98,22 @@ proc applyDeclarations(elem: Element, parent: CSSComputedValues, ua, user: Decla for rule in author: ares.applyImportant(rule[pseudo]) - let style = elem.attr("style") - if style.len > 0: - let inline_rules = newStringStream(style).parseListOfDeclarations2() - ares.applyNormal(inline_rules) - ares.applyImportant(inline_rules) + if styledNode.node != nil: + let style = Element(styledNode.node).attr("style") + if style.len > 0: + let inline_rules = newStringStream(style).parseListOfDeclarations2() + ares.applyNormal(inline_rules) + ares.applyImportant(inline_rules) ares.applyImportant(user[pseudo]) ares.applyImportant(ua[pseudo]) - result = StyledNode(t: STYLED_ELEMENT, node: elem, computed: parent.inheritProperties()) + styledNode.computed = parent.inheritProperties() for rule in ares.normal: - result.applyProperty(parent, rule) + styledNode.applyProperty(parent, rule) for rule in ares.important: - result.applyProperty(parent, rule) + styledNode.applyProperty(parent, rule) # Either returns a new styled node or nil. proc applyDeclarations(pseudo: PseudoElem, parent: CSSComputedValues, ua, user: DeclarationList, author: seq[DeclarationList]): StyledNode = @@ -146,23 +144,21 @@ func applyMediaQuery(ss: CSSStylesheet): CSSStylesheet = if mq.query.applies(): result.add(mq.children.applyMediaQuery()) -func calcRules(elem: Element, ua, user: CSSStylesheet, author: seq[CSSStylesheet]): tuple[uadecls, userdecls: DeclarationList, authordecls: seq[DeclarationList]] = - result.uadecls = calcRules(elem, ua) - result.userdecls = calcRules(elem, user) +func calcRules(styledNode: StyledNode, ua, user: CSSStylesheet, author: seq[CSSStylesheet]): tuple[uadecls, userdecls: DeclarationList, authordecls: seq[DeclarationList]] = + result.uadecls = calcRules(styledNode, ua) + result.userdecls = calcRules(styledNode, user) for rule in author: - result.authordecls.add(calcRules(elem, rule)) + result.authordecls.add(calcRules(styledNode, rule)) -proc applyStyle(parent: StyledNode, elem: Element, uadecls, userdecls: DeclarationList, authordecls: seq[DeclarationList]): StyledNode = +proc applyStyle(parent, styledNode: StyledNode, uadecls, userdecls: DeclarationList, authordecls: seq[DeclarationList]) = let parentComputed = if parent != nil: parent.computed else: rootProperties() - result = elem.applyDeclarations(parentComputed, uadecls, userdecls, authordecls) - assert result != nil + styledNode.applyDeclarations(parentComputed, uadecls, userdecls, authordecls) # Builds a StyledNode tree, optionally based on a previously cached version. -# This was originally a recursive algorithm; it had to be rewritten iteratively proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledNode): StyledNode = if document.html == nil: return @@ -187,14 +183,17 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN continue var styledChild: StyledNode - if cachedChild != nil and (cachedChild.node == nil or cachedChild.node.nodeType != ELEMENT_NODE or Element(cachedChild.node).cssapplied): + if cachedChild != nil and cachedChild.isValid(): if cachedChild.t == STYLED_ELEMENT: - styledChild = StyledNode(t: STYLED_ELEMENT, pseudo: cachedChild.pseudo, computed: cachedChild.computed, node: cachedChild.node) - if cachedChild.pseudo != PSEUDO_NONE: + if cachedChild.pseudo == PSEUDO_NONE: + styledChild = styledParent.newStyledElement(Element(cachedChild.node), cachedChild.computed, cachedChild.depends) + else: + styledChild = styledParent.newStyledElement(cachedChild.pseudo, cachedChild.computed, cachedChild.depends) styledChild.children = cachedChild.children #TODO does this actually refresh pseudo elems when needed? else: # Text - styledChild = StyledNode(t: STYLED_TEXT, text: cachedChild.text, node: cachedChild.node) + styledChild = styledParent.newStyledText(cachedChild.text) + styledChild.node = cachedChild.node if styledParent == nil: # Root element result = styledChild @@ -202,7 +201,7 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN styledParent.children.add(styledChild) else: if pseudo != PSEUDO_NONE: - let (ua, user, authordecls) = Element(styledParent.node).calcRules(ua, user, author) + let (ua, user, authordecls) = styledParent.calcRules(ua, user, author) case pseudo of PSEUDO_BEFORE, PSEUDO_AFTER: let styledPseudo = pseudo.applyDeclarations(styledParent.computed, ua, user, authordecls) @@ -210,32 +209,34 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN styledParent.children.add(styledPseudo) let content = styledPseudo.computed{"content"} if content.len > 0: - styledPseudo.children.add(StyledNode(t: STYLED_TEXT, text: content)) + styledPseudo.children.add(styledPseudo.newStyledText(content)) of PSEUDO_INPUT_TEXT: let content = HTMLInputElement(styledParent.node).inputString() if content.len > 0: - styledChild = StyledNode(t: STYLED_TEXT, text: content) + styledChild = styledParent.newStyledText(content) styledParent.children.add(styledChild) of PSEUDO_NONE: discard else: assert child != nil if styledParent != nil: if child.nodeType == ELEMENT_NODE: - let (ua, user, authordecls) = Element(child).calcRules(ua, user, author) - styledChild = applyStyle(styledParent, Element(child), ua, user, authordecls) + styledChild = styledParent.newStyledElement(Element(child)) + let (ua, user, authordecls) = styledChild.calcRules(ua, user, author) + applyStyle(styledParent, styledChild, ua, user, authordecls) styledParent.children.add(styledChild) elif child.nodeType == TEXT_NODE: let text = Text(child) - styledChild = StyledNode(t: STYLED_TEXT, node: child, text: text.data) + styledChild = styledParent.newStyledText(text) styledParent.children.add(styledChild) else: # Root element - assert result == nil - let (ua, user, authordecls) = Element(child).calcRules(ua, user, author) - styledChild = applyStyle(styledParent, Element(child), ua, user, authordecls) + styledChild = newStyledElement(Element(child)) + let (ua, user, authordecls) = styledChild.calcRules(ua, user, author) + applyStyle(styledParent, styledChild, ua, user, authordecls) result = styledChild - if styledChild != nil and styledChild.node != nil and styledChild.node.nodeType == ELEMENT_NODE: + if styledChild != nil and styledChild.t == STYLED_ELEMENT and styledChild.node != nil: + styledChild.applyDependValues() template stack_append(styledParent: StyledNode, child: Node) = if cachedChild != nil: var cached: StyledNode @@ -280,8 +281,3 @@ proc applyStylesheets*(document: Document, uass, userss: CSSStylesheet, previous let uass = uass.applyMediaQuery() let userss = userss.applyMediaQuery() return document.applyRules(uass, userss, previousStyled) - -proc refreshStyle*(elem: Element) = - elem.cssapplied = false - for child in elem.children: - child.refreshStyle() diff --git a/src/css/select.nim b/src/css/select.nim index b43604c4..f1140d1e 100644 --- a/src/css/select.nim +++ b/src/css/select.nim @@ -1,12 +1,9 @@ -import unicode import tables import strutils -import sequtils -import sugar -import streams -import css/selectorparser import css/cssparser +import css/selectorparser +import css/stylednode import html/dom import html/tags @@ -14,7 +11,7 @@ func attrSelectorMatches(elem: Element, sel: Selector): bool = case sel.rel of ' ': return sel.attr in elem.attributes of '=': return elem.attr(sel.attr) == sel.value - of '~': return sel.value in unicode.split(elem.attr(sel.attr)) + of '~': return sel.value in elem.attr(sel.attr).split(Whitespace) of '|': let val = elem.attr(sel.attr) return val == sel.value or sel.value.startsWith(val & '-') @@ -23,12 +20,17 @@ func attrSelectorMatches(elem: Element, sel: Selector): bool = of '*': return elem.attr(sel.attr).contains(sel.value) else: return false -func pseudoSelectorMatches(elem: Element, sel: Selector): bool = +func pseudoSelectorMatches[T: Element|StyledNode](elem: T, sel: Selector, felem: T): bool = + let selem = elem + when elem is StyledNode: + let elem = Element(elem.node) case sel.pseudo of PSEUDO_FIRST_CHILD: return elem.parentNode.firstElementChild == elem of PSEUDO_LAST_CHILD: return elem.parentNode.lastElementChild == elem of PSEUDO_ONLY_CHILD: return elem.parentNode.firstElementChild == elem and elem.parentNode.lastElementChild == elem - of PSEUDO_HOVER: return elem.hover + of PSEUDO_HOVER: + when selem is StyledNode: felem.depends.nodes[DEPEND_HOVER].add(selem) + return elem.hover of PSEUDO_ROOT: return elem == elem.document.html of PSEUDO_NTH_CHILD: let n = int64(sel.pseudonum - 1) @@ -39,68 +41,101 @@ func pseudoSelectorMatches(elem: Element, sel: Selector): bool = inc i return false of PSEUDO_CHECKED: + when selem is StyledNode: felem.depends.nodes[DEPEND_CHECKED].add(selem) if elem.tagType == TAG_INPUT: return HTMLInputElement(elem).checked elif elem.tagType == TAG_OPTION: return HTMLOptionElement(elem).selected return false -func selectorsMatch*(elem: Element, selectors: SelectorList): bool +func selectorsMatch*[T: Element|StyledNode](elem: T, selectors: SelectorList, felem: T = nil): bool -func funcSelectorMatches(elem: Element, sel: Selector): bool = +func funcSelectorMatches[T: Element|StyledNode](elem: T, sel: Selector, felem: T): bool = case sel.name of "not": for slist in sel.fsels: - if elem.selectorsMatch(slist): + if elem.selectorsMatch(slist, felem): return false return true of "is", "where": for slist in sel.fsels: - if elem.selectorsMatch(slist): + if elem.selectorsMatch(slist, felem): return true return false else: discard -func combinatorSelectorMatches(elem: Element, sel: Selector): bool = +func combinatorSelectorMatches[T: Element|StyledNode](elem: T, sel: Selector, felem: T): bool = + let selem = elem #combinator without at least two members makes no sense assert sel.csels.len > 1 - if elem.selectorsMatch(sel.csels[^1]): + if selem.selectorsMatch(sel.csels[^1], felem): var i = sel.csels.len - 2 case sel.ct of DESCENDANT_COMBINATOR: - var e = elem.parentElement + when selem is StyledNode: + var e = elem.parent + else: + var e = elem.parentElement while e != nil and i >= 0: - if e.selectorsMatch(sel.csels[i]): + if e.selectorsMatch(sel.csels[i], felem): dec i - e = e.parentElement + when elem is StyledNode: + e = e.parent + else: + e = e.parentElement of CHILD_COMBINATOR: - var e = elem.parentElement + when elem is StyledNode: + var e = elem.parent + else: + var e = elem.parentElement while e != nil and i >= 0: - if not e.selectorsMatch(sel.csels[i]): + if not e.selectorsMatch(sel.csels[i], felem): return false dec i - e = e.parentElement + when elem is StyledNode: + e = e.parent + else: + e = e.parentElement of NEXT_SIBLING_COMBINATOR: var found = false - for child in elem.parentElement.children_rev: + when elem is StyledNode: + var parent = elem.parent + else: + var parent = elem.parentElement + for child in parent.children_rev: + when elem is StyledNode: + if child.t != STYLED_ELEMENT or child.node == nil: continue if found: - if not child.selectorsMatch(sel.csels[i]): + if not child.selectorsMatch(sel.csels[i], felem): return false dec i + if i < 0: + return true if child == elem: found = true of SUBSEQ_SIBLING_COMBINATOR: var found = false - for child in elem.parentElement.children_rev: + when selem is StyledNode: + var parent = selem.parent + else: + var parent = elem.parentElement + for child in parent.children_rev: + when selem is StyledNode: + if child.t != STYLED_ELEMENT or child.node == nil: continue if found: - if child.selectorsMatch(sel.csels[i]): + if child.selectorsMatch(sel.csels[i], felem): dec i - if child == elem: + if i < 0: + return true + if child == selem: found = true return i == -1 return false -func selectorMatches(elem: Element, sel: Selector): bool = +func selectorMatches[T: Element|StyledNode](elem: T, sel: Selector, felem: T): bool = + let selem = elem + when elem is StyledNode: + let elem = Element(selem.node) case sel.t of TYPE_SELECTOR: return elem.tagType == sel.tag @@ -111,78 +146,86 @@ func selectorMatches(elem: Element, sel: Selector): bool = of ATTR_SELECTOR: return elem.attrSelectorMatches(sel) of PSEUDO_SELECTOR: - return pseudoSelectorMatches(elem, sel) + return pseudoSelectorMatches(selem, sel, felem) of PSELEM_SELECTOR: return true of UNIVERSAL_SELECTOR: return true of FUNC_SELECTOR: - return funcSelectorMatches(elem, sel) + return funcSelectorMatches(selem, sel, felem) of COMBINATOR_SELECTOR: - return combinatorSelectorMatches(elem, sel) + return combinatorSelectorMatches(selem, sel, felem) + +# WARNING for StyledNode, this has the side effect of modifying depends. +#TODO make that an explicit flag or something, also get rid of the Element case +func selectorsMatch*[T: Element|StyledNode](elem: T, selectors: SelectorList, felem: T = nil): bool = + let felem = if felem != nil: + felem + else: + elem -func selectorsMatch*(elem: Element, selectors: SelectorList): bool = for sel in selectors.sels: - if not selectorMatches(elem, sel): + if not selectorMatches(elem, sel, felem): return false return true -func selectElems(element: Element, sel: Selector): seq[Element] = - case sel.t - of TYPE_SELECTOR: - return element.filterDescendants((elem) => elem.tagType == sel.tag) - of ID_SELECTOR: - return element.filterDescendants((elem) => elem.id == sel.id) - of CLASS_SELECTOR: - return element.filterDescendants((elem) => sel.class in elem.classList) - of UNIVERSAL_SELECTOR: - return element.all_descendants - of ATTR_SELECTOR: - return element.filterDescendants((elem) => attrSelectorMatches(elem, sel)) - of PSEUDO_SELECTOR: - return element.filterDescendants((elem) => pseudoSelectorMatches(elem, sel)) - of PSELEM_SELECTOR: - return element.all_descendants - of FUNC_SELECTOR: - return element.filterDescendants((elem) => selectorMatches(elem, sel)) - of COMBINATOR_SELECTOR: - return element.filterDescendants((elem) => selectorMatches(elem, sel)) - -func selectElems(element: Element, selectors: SelectorList): seq[Element] = - assert(selectors.len > 0) - let sellist = optimizeSelectorList(selectors) - result = element.selectElems(selectors[0]) - var i = 1 - - while i < sellist.len: - result = result.filter((elem) => selectorMatches(elem, sellist[i])) - inc i - -proc querySelectorAll*(document: Document, q: string): seq[Element] = - let ss = newStringStream(q) - let cvals = parseListOfComponentValues(ss) - let selectors = parseSelectors(cvals) - - if document.html != nil: - for sel in selectors: - result.add(document.html.selectElems(sel)) - -proc querySelector*(document: Document, q: string): Element = - let elems = document.querySelectorAll(q) - if elems.len > 0: - return elems[0] - return nil - -proc querySelectorAll*(element: Element, q: string): seq[Element] = - let ss = newStringStream(q) - let cvals = parseListOfComponentValues(ss) - let selectors = parseSelectors(cvals) - - for sel in selectors: - result.add(element.selectElems(sel)) - -proc querySelector*(element: Element, q: string): Element = - let elems = element.querySelectorAll(q) - if elems.len > 0: - return elems[0] - return nil +#TODO idk, it's not like we have JS anyways +#func selectElems[T: Element|StyledNode](element: T, sel: Selector, felem: T): seq[T] = +# case sel.t +# of TYPE_SELECTOR: +# return element.filterDescendants((elem) => elem.tagType == sel.tag) +# of ID_SELECTOR: +# return element.filterDescendants((elem) => elem.id == sel.id) +# of CLASS_SELECTOR: +# return element.filterDescendants((elem) => sel.class in elem.classList) +# of UNIVERSAL_SELECTOR: +# return element.all_descendants +# of ATTR_SELECTOR: +# return element.filterDescendants((elem) => attrSelectorMatches(elem, sel)) +# of PSEUDO_SELECTOR: +# return element.filterDescendants((elem) => pseudoSelectorMatches(elem, sel, felem)) +# of PSELEM_SELECTOR: +# return element.all_descendants +# of FUNC_SELECTOR: +# return element.filterDescendants((elem) => selectorMatches(elem, sel)) +# of COMBINATOR_SELECTOR: +# return element.filterDescendants((elem) => selectorMatches(elem, sel)) +# +#func selectElems(element: Element, selectors: SelectorList): seq[Element] = +# assert(selectors.len > 0) +# let sellist = optimizeSelectorList(selectors) +# result = element.selectElems(selectors[0], element) +# var i = 1 +# +# while i < sellist.len: +# result = result.filter((elem) => selectorMatches(elem, sellist[i], elem)) +# inc i +# +#proc querySelectorAll*(document: Document, q: string): seq[Element] = +# let ss = newStringStream(q) +# let cvals = parseListOfComponentValues(ss) +# let selectors = parseSelectors(cvals) +# +# if document.html != nil: +# for sel in selectors: +# result.add(document.html.selectElems(sel)) +# +#proc querySelector*(document: Document, q: string): Element = +# let elems = document.querySelectorAll(q) +# if elems.len > 0: +# return elems[0] +# return nil +# +#proc querySelectorAll*(element: Element, q: string): seq[Element] = +# let ss = newStringStream(q) +# let cvals = parseListOfComponentValues(ss) +# let selectors = parseSelectors(cvals) +# +# for sel in selectors: +# result.add(element.selectElems(sel)) +# +#proc querySelector*(element: Element, q: string): Element = +# let elems = element.querySelectorAll(q) +# if elems.len > 0: +# return elems[0] +# return nil diff --git a/src/css/stylednode.nim b/src/css/stylednode.nim index d6293187..6c306f21 100644 --- a/src/css/stylednode.nim +++ b/src/css/stylednode.nim @@ -1,18 +1,123 @@ +import css/selectorparser import css/values import html/dom +import html/tags # Container to hold a style and a node. -# Pseudo elements are implemented using StyledNode objects without nodes. +# Pseudo-elements are implemented using StyledNode objects without nodes. Input +# elements are implemented as internal "pseudo-elements." +# +# To avoid having to invalidate the entire tree on pseudo-class changes, each +# node holds a list of nodes their CSS values depend on. (This list may include +# the node itself.) In addition, nodes also store each value valid for +# dependency d. These are then used for checking the validity of StyledNodes. +# +# In other words - say we have to apply the author stylesheets of the following +# document: +# +# <style> +# div:hover { color: red; } +# :not(input:checked) + p { display: none; } +# </style> +# <div>This div turns red on hover.</div> +# <input type=checkbox> +# <p>This paragraph is only shown when the checkbox above is checked. +# +# That produces the following dependency graph (simplified): +# div -> div (hover) +# p -> input (checked) +# +# Then, to check if a node has been invalidated, we just iterate over all +# recorded dependencies of each StyledNode, and check if their registered value +# of the pseudo-class still matches that of its associated element. +# +# So in our example, for div we check if div's :hover pseudo-class has changed, +# for p we check whether input's :checked pseudo-class has changed. + type StyledType* = enum STYLED_ELEMENT, STYLED_TEXT + DependencyType* = enum + DEPEND_HOVER, DEPEND_CHECKED + + InvalidationRegistry* = set[DependencyType] + + DependencyInfo* = object + # All nodes we depend on, for each dependency type d. + nodes*: array[DependencyType, seq[StyledNode]] + # Previous value. Node is marked invalid when one of these no longer + # matches the DOM value. + prev: array[DependencyType, bool] + StyledNode* = ref object + parent*: StyledNode + node*: Node case t*: StyledType + of STYLED_TEXT: + text*: string of STYLED_ELEMENT: pseudo*: PseudoElem computed*: CSSComputedValues - of STYLED_TEXT: - text*: string - node*: Node - children*: seq[StyledNode] + children*: seq[StyledNode] + depends*: DependencyInfo + +iterator branch*(node: StyledNode): StyledNode {.inline.} = + var node = node + while node != nil: + yield node + node = node.parent + +iterator children_rev*(node: StyledNode): StyledNode {.inline.} = + for i in countdown(node.children.high, 0): + yield node.children[i] + +func checked(element: Element): bool = + if element.tagType == TAG_INPUT: + let input = HTMLInputElement(element) + result = input.checked + +func isValid*(styledNode: StyledNode): bool = + if styledNode.t == STYLED_TEXT: + return true + if styledNode.node != nil and Element(styledNode.node).invalid: + return false + for d in DependencyType: + for child in styledNode.depends.nodes[d]: + assert child.node != nil + let elem = Element(child.node) + case d + of DEPEND_HOVER: + if child.depends.prev[d] != elem.hover: + return false + of DEPEND_CHECKED: + if child.depends.prev[d] != elem.checked: + return false + return styledNode.parent == nil or styledNode.parent.isValid() + +proc applyDependValues*(styledNode: StyledNode) = + let elem = Element(styledNode.node) + styledNode.depends.prev[DEPEND_HOVER] = elem.hover + styledNode.depends.prev[DEPEND_CHECKED] = elem.checked + elem.invalid = false + +func newStyledElement*(parent: StyledNode, element: Element, computed: CSSComputedValues, reg: sink DependencyInfo): StyledNode = + result = StyledNode(t: STYLED_ELEMENT, computed: computed, node: element, parent: parent) + result.depends = reg + +func newStyledElement*(parent: StyledNode, element: Element): StyledNode = + result = StyledNode(t: STYLED_ELEMENT, node: element, parent: parent) + +# Root +func newStyledElement*(element: Element): StyledNode = + result = StyledNode(t: STYLED_ELEMENT, node: element) + +func newStyledElement*(parent: StyledNode, pseudo: PseudoElem, computed: CSSComputedValues, reg: sink DependencyInfo): StyledNode = + result = StyledNode(t: STYLED_ELEMENT, computed: computed, pseudo: pseudo, parent: parent) + result.depends = reg + +func newStyledText*(parent: StyledNode, text: string): StyledNode = + result = StyledNode(t: STYLED_TEXT, text: text, parent: parent) + +func newStyledText*(parent: StyledNode, text: Text): StyledNode = + result = StyledNode(t: STYLED_TEXT, text: text.data, node: text, parent: parent) diff --git a/src/css/values.nim b/src/css/values.nim index be8f5305..ec172e8d 100644 --- a/src/css/values.nim +++ b/src/css/values.nim @@ -589,7 +589,7 @@ func cssDisplay(d: CSSDeclaration): CSSDisplay = of "inline": return DISPLAY_INLINE of "list-item": return DISPLAY_LIST_ITEM of "inline-block": return DISPLAY_INLINE_BLOCK - of "table": return DISPLAY_TABLE + #of "table": return DISPLAY_TABLE # of "table-row": return DISPLAY_TABLE_ROW # of "table-cell": return DISPLAY_TABLE_CELL # of "table-column": return DISPLAY_TABLE_COLUMN |