about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/css/cascade.nim34
-rw-r--r--src/css/stylednode.nim2
-rw-r--r--src/html/dom.nim39
-rw-r--r--src/html/htmlparser.nim6
4 files changed, 28 insertions, 53 deletions
diff --git a/src/css/cascade.nim b/src/css/cascade.nim
index 68b9ebee..c7d6dfd0 100644
--- a/src/css/cascade.nim
+++ b/src/css/cascade.nim
@@ -234,20 +234,15 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN
     return
 
   var author: seq[CSSStylesheet]
+  for sheet in document.sheets():
+    author.add(sheet.applyMediaQuery())
 
-  var lenstack = newSeqOfCap[int](256)
   var styledStack: seq[CascadeLevel]
   styledStack.add((nil, document.html, PSEUDO_NONE, cachedTree))
 
   while styledStack.len > 0:
     var (styledParent, child, pseudo, cachedChild) = styledStack.pop()
 
-    # Remove stylesheets on nil
-    if pseudo == PSEUDO_NONE and child == nil:
-      let len = lenstack.pop()
-      author.setLen(author.len - len)
-      continue
-
     var styledChild: StyledNode
     let valid = cachedChild != nil and cachedChild.isValid()
     if valid:
@@ -370,31 +365,6 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN
           styledStack.add((styledParent, nil, ps, nil))
 
       let elem = Element(styledChild.node)
-      if valid and result != styledChild:
-        styledChild.sheets = cachedChild.sheets
-      else:
-        if result == styledChild:
-          #TODO this is ugly. we should cache head sheets separately.
-          let head = document.head
-          if head != nil:
-            if head.invalid or cachedChild == nil:
-              let sheets = head.sheets()
-              for sheet in sheets:
-                styledChild.sheets.add(sheet.applyMediaQuery())
-            else:
-              styledChild.sheets = cachedChild.sheets
-        else:
-          let sheets = elem.sheets()
-          if sheets.len > 0:
-            for sheet in sheets:
-              styledChild.sheets.add(sheet.applyMediaQuery())
-      if styledChild.sheets.len > 0:
-        for sheet in styledChild.sheets:
-          author.add(sheet)
-        lenstack.add(styledChild.sheets.len)
-        # Add a nil before the last element (in-stack), so we know when to
-        # remove inline author sheets.
-        styledStack.add((nil, nil, PSEUDO_NONE, nil))
 
       stack_append styledChild, PSEUDO_AFTER
 
diff --git a/src/css/stylednode.nim b/src/css/stylednode.nim
index 30358b29..c18c8779 100644
--- a/src/css/stylednode.nim
+++ b/src/css/stylednode.nim
@@ -1,5 +1,4 @@
 import css/selectorparser
-import css/sheet
 import css/values
 import html/dom
 import html/tags
@@ -60,7 +59,6 @@ type
       computed*: CSSComputedValues
       children*: seq[StyledNode]
       depends*: DependencyInfo
-      sheets*: seq[CSSStylesheet]
     of STYLED_REPLACEMENT: # replaced elements: quotes, or (TODO) markers, images
       content*: CSSContent
 
diff --git a/src/html/dom.nim b/src/html/dom.nim
index 37ba4323..355fc3c1 100644
--- a/src/html/dom.nim
+++ b/src/html/dom.nim
@@ -179,6 +179,9 @@ type
     invalidCollections: HashSet[int] # collection ids
     colln: int
 
+    cachedSheets: seq[CSSStylesheet]
+    cachedSheetsInvalid: bool
+
   CharacterData* = ref object of Node
     data* {.jsget.}: string
 
@@ -256,7 +259,6 @@ type
 
   HTMLStyleElement* = ref object of HTMLElement
     sheet*: CSSStylesheet
-    sheet_invalid*: bool
 
   HTMLLinkElement* = ref object of HTMLElement
     sheet*: CSSStylesheet
@@ -1072,17 +1074,23 @@ func crossorigin(element: HTMLScriptElement): CORSAttribute =
 func referrerpolicy(element: HTMLScriptElement): Option[ReferrerPolicy] =
   getReferrerPolicy(element.attr("referrerpolicy"))
 
-proc sheets*(element: Element): seq[CSSStylesheet] =
-  for child in element.elementList:
-    if child.tagType == TAG_STYLE:
-      let child = HTMLStyleElement(child)
-      if child.sheet_invalid:
-        child.sheet = parseStylesheet(newStringStream(child.textContent))
-      result.add(child.sheet)
-    elif child.tagType == TAG_LINK:
-      let child = HTMLLinkElement(child)
-      if child.sheet != nil:
-        result.add(child.sheet)
+proc sheets*(document: Document): seq[CSSStylesheet] =
+  if document.cachedSheetsInvalid:
+    document.cachedSheets.setLen(0)
+    for elem in document.html.elements({TAG_STYLE, TAG_LINK}):
+      case elem.tagType
+      of TAG_STYLE:
+        let style = HTMLStyleElement(elem)
+        style.sheet = parseStylesheet(newStringStream(style.textContent))
+        if style.sheet != nil:
+          document.cachedSheets.add(style.sheet)
+      of TAG_LINK:
+        let link = HTMLLinkElement(elem)
+        if link.sheet != nil:
+          document.cachedSheets.add(link.sheet)
+      else: discard
+    document.cachedSheetsInvalid = false
+  return document.cachedSheets
 
 func inputString*(input: HTMLInputElement): string =
   case input.inputType
@@ -1326,7 +1334,6 @@ func newHTMLElement*(document: Document, tagType: TagType, namespace = Namespace
     result = new(HTMLLIElement)
   of TAG_STYLE:
     result = new(HTMLStyleElement)
-    HTMLStyleElement(result).sheet_invalid = true
   of TAG_LINK:
     result = new(HTMLLinkElement)
   of TAG_FORM:
@@ -1653,6 +1660,9 @@ proc remove*(node: Node, index: int, suppressObservers: bool) =
   node.parentNode = nil
   node.parentElement = nil
   node.root = nil
+  if node.nodeType == ELEMENT_NODE:
+    if Element(node).tagType in {TAG_STYLE, TAG_LINK} and node.document != nil:
+      node.document.cachedSheetsInvalid = true
 
   #TODO assigned, shadow root, shadow root again, custom nodes, registered observers
   #TODO not suppress observers => queue tree mutation record
@@ -1687,6 +1697,9 @@ proc applyChildInsert(parent, child: Node, index: int) =
     child.nextSibling = parent.childList[index + 1]
     child.nextSibling.previousSibling = child
   child.invalidateCollections()
+  if child.nodeType == ELEMENT_NODE:
+    if Element(child).tagType in {TAG_STYLE, TAG_LINK} and child.document != nil:
+      child.document.cachedSheetsInvalid = true
 
 proc resetElement*(element: Element) = 
   case element.tagType
diff --git a/src/html/htmlparser.nim b/src/html/htmlparser.nim
index 5467e321..bee1ed9d 100644
--- a/src/html/htmlparser.nim
+++ b/src/html/htmlparser.nim
@@ -330,12 +330,6 @@ template insert_character_impl(parser: var HTML5Parser, data: typed) =
     let text = location.inside.document.createTextNode($data)
     location.insert(text)
 
-  if location.inside.nodeType == ELEMENT_NODE:
-    let parent = Element(location.inside)
-    if parent.tagType == TAG_STYLE:
-      let parent = HTMLStyleElement(parent)
-      parent.sheet_invalid = true
-
 proc insertCharacter(parser: var HTML5Parser, data: string) =
   insert_character_impl(parser, data)