about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/css/cascade.nim13
-rw-r--r--src/css/stylednode.nim6
-rw-r--r--src/css/values.nim2
-rw-r--r--src/layout/engine.nim62
4 files changed, 48 insertions, 35 deletions
diff --git a/src/css/cascade.nim b/src/css/cascade.nim
index 25866ac0..9d2e9d53 100644
--- a/src/css/cascade.nim
+++ b/src/css/cascade.nim
@@ -174,7 +174,7 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN
   styledStack.add((nil, document.html, PSEUDO_NONE, cachedTree))
 
   while styledStack.len > 0:
-    let (styledParent, child, pseudo, cachedChild) = styledStack.pop()
+    var (styledParent, child, pseudo, cachedChild) = styledStack.pop()
 
     # Remove stylesheets on nil
     if pseudo == PSEUDO_NONE and child == nil:
@@ -200,6 +200,7 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN
       else:
         styledParent.children.add(styledChild)
     else:
+      cachedChild = nil
       if pseudo != PSEUDO_NONE:
         let (ua, user, authordecls) = styledParent.calcRules(ua, user, author)
         case pseudo
@@ -255,7 +256,12 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN
             if it.t == STYLED_ELEMENT and it.pseudo == ps:
               cached = it
               break
-          styledStack.add((styledParent, nil, ps, cached))
+          # When calculating pseudo-element rules, their dependencies are added
+          # to their parent's dependency list, which in turn invalidates the
+          # parent and thus recalculates all pseudo-elements.
+          # In other words, we can just do this:
+          if cached != nil:
+            styledStack.add((styledParent, nil, ps, cached))
         else:
           styledStack.add((styledParent, nil, ps, nil))
 
@@ -271,7 +277,8 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN
       stack_append styledChild, PSEUDO_AFTER
 
       for i in countdown(elem.childNodes.high, 0):
-        stack_append styledChild, elem.childNodes[i]
+        if elem.childNodes[i].nodeType in {ELEMENT_NODE, TEXT_NODE}:
+          stack_append styledChild, elem.childNodes[i]
 
       if elem.tagType == TAG_INPUT:
         stack_append styledChild, PSEUDO_INPUT_TEXT
diff --git a/src/css/stylednode.nim b/src/css/stylednode.nim
index 6c306f21..8586bee4 100644
--- a/src/css/stylednode.nim
+++ b/src/css/stylednode.nim
@@ -93,7 +93,7 @@ func isValid*(styledNode: StyledNode): bool =
       of DEPEND_CHECKED:
         if child.depends.prev[d] != elem.checked:
           return false
-  return styledNode.parent == nil or styledNode.parent.isValid()
+  return true
 
 proc applyDependValues*(styledNode: StyledNode) =
   let elem = Element(styledNode.node)
@@ -104,9 +104,11 @@ proc applyDependValues*(styledNode: StyledNode) =
 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
+  result.parent = parent
 
 func newStyledElement*(parent: StyledNode, element: Element): StyledNode =
   result = StyledNode(t: STYLED_ELEMENT, node: element, parent: parent)
+  result.parent = parent
 
 # Root
 func newStyledElement*(element: Element): StyledNode =
@@ -118,6 +120,8 @@ func newStyledElement*(parent: StyledNode, pseudo: PseudoElem, computed: CSSComp
 
 func newStyledText*(parent: StyledNode, text: string): StyledNode =
   result = StyledNode(t: STYLED_TEXT, text: text, parent: parent)
+  result.parent = parent
 
 func newStyledText*(parent: StyledNode, text: Text): StyledNode =
   result = StyledNode(t: STYLED_TEXT, text: text.data, node: text, parent: parent)
+  result.parent = parent
diff --git a/src/css/values.nim b/src/css/values.nim
index ec172e8d..9c1a93c9 100644
--- a/src/css/values.nim
+++ b/src/css/values.nim
@@ -241,7 +241,7 @@ func em_to_px(em: float64, term: TermAttributes): int =
 func ch_to_px(ch: float64, term: TermAttributes): int =
   int(ch * float64(term.ppc))
 
-# 水 width, we assume it's 2 chars (TODO make width() work at comptime)
+# 水 width, we assume it's 2 chars
 func ic_to_px(ic: float64, term: TermAttributes): int =
   int(ic * float64(term.ppc) * 2)
 
diff --git a/src/layout/engine.nim b/src/layout/engine.nim
index 18af9e7b..00641ae1 100644
--- a/src/layout/engine.nim
+++ b/src/layout/engine.nim
@@ -692,7 +692,7 @@ proc getTableRowBox(computed: CSSComputedValues): TableRowBoxBuilder =
   result.computed = computed.copyProperties()
 
 type BlockGroup = object
-  parent: BlockBoxBuilder
+  parent: BoxBuilder
   boxes: seq[BoxBuilder]
   listItemCounter: int
 
@@ -719,13 +719,13 @@ template flush_ibox() =
     blockgroup.add(ibox)
     ibox = nil
 
-proc newBlockGroup(parent: BlockBoxBuilder): BlockGroup =
+proc newBlockGroup(parent: BoxBuilder): BlockGroup =
   result.parent = parent
   result.listItemCounter = 1
 
 proc generateBlockBox(styledNode: StyledNode, viewport: Viewport, marker = none(MarkerBoxBuilder)): BlockBoxBuilder
 
-proc generateInlineBoxes(box: BlockBoxBuilder, styledNode: StyledNode, blockgroup: var BlockGroup, viewport: Viewport)
+proc generateInlineBoxes(box: BoxBuilder, styledNode: StyledNode, blockgroup: var BlockGroup, viewport: Viewport)
 
 proc generateFromElem(styledNode: StyledNode, blockgroup: var BlockGroup, viewport: Viewport, ibox: var InlineBoxBuilder) =
   let box = blockgroup.parent
@@ -768,7 +768,7 @@ proc generateFromElem(styledNode: StyledNode, blockgroup: var BlockGroup, viewpo
   else:
     discard #TODO
 
-proc generateInlineBoxes(box: BlockBoxBuilder, styledNode: StyledNode, blockgroup: var BlockGroup, viewport: Viewport) =
+proc generateInlineBoxes(box: BoxBuilder, styledNode: StyledNode, blockgroup: var BlockGroup, viewport: Viewport) =
   var ibox: InlineBoxBuilder = nil
 
   for child in styledNode.children:
@@ -822,34 +822,36 @@ const ProperTableRowParent = {DISPLAY_TABLE} + RowGroupBox #TODO inline-table bo
 const InternalTableBox = {DISPLAY_TABLE_CELL, DISPLAY_TABLE_ROW, DISPLAY_TABLE_COLUMN, DISPLAY_TABLE_COLUMN_GROUP} + RowGroupBox
 const TabularContainer = {DISPLAY_TABLE_ROW} + ProperTableRowParent
 
-proc generateTableBox(styledNode: StyledNode, viewport: Viewport): TableBox =
+proc generateTableRowBox(styledNode: StyledNode, viewport: Viewport): TableRowBoxBuilder =
   discard
-  #let box = getTableBox(styledNode.computed)
-  #var blockgroup = newBlockGroup(box)
-  #var ibox: InlineBoxBuilder = nil
-  #var listItemCounter = 1
-
-  #for child in styledNode.children:
-  #  if child.t == STYLED_ELEMENT:
-  #    generateFromElem(child, blockgroup, viewport, ibox)
-  #  else:
-  #    if canGenerateAnonymousInline(blockgroup, box.computed, child.text):
-  #      if ibox == nil:
-  #        ibox = getTextBox(styledNode.computed)
-  #        ibox.node = styledNode.node
-  #      ibox.text.add(child.text)
-
-  #flush_ibox
-  #blockgroup.flush()
-
-  ## Generate missing child wrappers
-  #var anonRow: TableRowBoxBuilder
-  #for child in box.children:
-  #  if child.computed{"display"} notin ProperTableChild:
-  #    if anonRow != nil:
-  #      anonRow = getTableRowBox(box.computed.inheritProperties())
-  #    discard
 
+proc generateTableBox(styledNode: StyledNode, viewport: Viewport): TableBoxBuilder =
+  let box = getTableBox(styledNode.computed)
+  var blockgroup = newBlockGroup(box)
+  var ibox: InlineBoxBuilder = nil
+  var listItemCounter = 1
+
+  for child in styledNode.children:
+    if child.t == STYLED_ELEMENT:
+      generateFromElem(child, blockgroup, viewport, ibox)
+    else:
+      if canGenerateAnonymousInline(blockgroup, box.computed, child.text):
+        if ibox == nil:
+          ibox = getTextBox(styledNode.computed)
+          ibox.node = styledNode
+        ibox.text.add(child.text)
+
+  flush_ibox
+  blockgroup.flush()
+
+  # Generate missing child wrappers
+  var anonRow: TableRowBoxBuilder
+  for child in box.children:
+    if child.computed{"display"} notin ProperTableChild:
+      if anonRow != nil:
+        anonRow = getTableRowBox(box.computed.inheritProperties())
+      discard
+  return box
 
 #proc generateFromElemTable(styledNode: StyledNode, viewport: Viewport, table: TableBoxBuilder = nil, parent: BoxBuilder = nil): BlockBox =
 #  case styledNode.computed{"display"}