about summary refs log tree commit diff stats
path: root/src/css
diff options
context:
space:
mode:
Diffstat (limited to 'src/css')
-rw-r--r--src/css/cascade.nim399
-rw-r--r--src/css/cssvalues.nim5
-rw-r--r--src/css/layout.nim19
-rw-r--r--src/css/match.nim2
-rw-r--r--src/css/selectorparser.nim10
-rw-r--r--src/css/stylednode.nim72
6 files changed, 124 insertions, 383 deletions
diff --git a/src/css/cascade.nim b/src/css/cascade.nim
index 0b4369df..7fff1434 100644
--- a/src/css/cascade.nim
+++ b/src/css/cascade.nim
@@ -7,14 +7,13 @@ import css/cssparser
 import css/cssvalues
 import css/lunit
 import css/match
-import css/mediaquery
 import css/selectorparser
 import css/sheet
-import css/stylednode
 import html/catom
 import html/dom
 import html/enums
 import html/script
+import types/bitmap
 import types/color
 import types/jscolor
 import types/opt
@@ -46,6 +45,7 @@ type
 proc applyValue(vals: CSSValues; entry: CSSComputedEntry;
   parentComputed, previousOrigin: CSSValues; initMap: var InitMap;
   initType: InitType; nextInitType: set[InitType]; window: Window)
+proc applyStyle*(element: Element)
 
 proc calcRule(tosorts: var ToSorts; element: Element;
     depends: var DependencyInfo; rule: CSSRuleDef) =
@@ -63,9 +63,8 @@ proc add(entry: var RuleListEntry; rule: CSSRuleDef) =
   entry.normalVars.add(rule.normalVars)
   entry.importantVars.add(rule.importantVars)
 
-proc calcRules(map: var RuleListMap; styledNode: StyledNode;
-    sheet: CSSStylesheet; origin: CSSOrigin) =
-  let element = styledNode.element
+proc calcRules(map: var RuleListMap; element: Element;
+    sheet: CSSStylesheet; origin: CSSOrigin; depends: var DependencyInfo) =
   var rules: seq[CSSRuleDef] = @[]
   sheet.tagTable.withValue(element.localName, v):
     rules.add(v[])
@@ -82,7 +81,7 @@ proc calcRules(map: var RuleListMap; styledNode: StyledNode;
     rules.add(rule)
   var tosorts = ToSorts.default
   for rule in rules:
-    tosorts.calcRule(element, styledNode.element.depends, rule)
+    tosorts.calcRule(element, depends, rule)
   for pseudo, it in tosorts.mpairs:
     it.sort(proc(x, y: RulePair): int =
       let n = cmp(x.specificity, y.specificity)
@@ -278,12 +277,14 @@ proc applyPresHints(computed: CSSValues; element: Element;
       set_cv cptHeight, length, resolveLength(cuEm, float32(size), attrs)
   else: discard
 
-proc applyDeclarations0(rules: RuleList; parent, element: Element;
+proc applyDeclarations(rules: RuleList; parent, element: Element;
     window: Window): CSSValues =
   result = CSSValues()
   var parentComputed: CSSValues = nil
   var parentVars: CSSVariableMap = nil
   if parent != nil:
+    if parent.computed == nil:
+      parent.applyStyle()
     parentComputed = parent.computed
     parentVars = parentComputed.vars
   for origin in CSSOrigin:
@@ -352,25 +353,17 @@ func hasValues(rules: RuleList): bool =
       return true
   return false
 
-func applyMediaQuery(ss: CSSStylesheet; window: Window): CSSStylesheet =
-  if ss == nil:
-    return nil
-  var res = CSSStylesheet()
-  res[] = ss[]
-  for mq in ss.mqList:
-    if mq.query.applies(window.settings.scripting, window.attrsp):
-      res.add(mq.children.applyMediaQuery(window))
-  return res
-
-proc applyDeclarations(styledNode: StyledNode; parent: Element;
-    window: Window; ua, user: CSSStylesheet; author: seq[CSSStylesheet]) =
+proc applyStyle*(element: Element) =
+  let document = element.document
+  let window = document.window
+  var depends = DependencyInfo.default
   var map = RuleListMap.default
-  map.calcRules(styledNode, ua, coUserAgent)
-  if user != nil:
-    map.calcRules(styledNode, user, coUser)
-  for rule in author:
-    map.calcRules(styledNode, rule, coAuthor)
-  let style = styledNode.element.cachedStyle
+  for sheet in document.uaSheets:
+    map.calcRules(element, sheet, coUserAgent, depends)
+  map.calcRules(element, document.userSheet, coUser, depends)
+  for sheet in document.authorSheets:
+    map.calcRules(element, sheet, coAuthor, depends)
+  let style = element.cachedStyle
   if window.styling and style != nil:
     for decl in style.decls:
       #TODO variables
@@ -380,263 +373,111 @@ proc applyDeclarations(styledNode: StyledNode; parent: Element;
         map[peNone][coAuthor].important.add(vals)
       else:
         map[peNone][coAuthor].normal.add(vals)
-  let element = styledNode.element
-  element.computedMap[peNone] = map[peNone].applyDeclarations0(parent, element,
-    window)
+  element.applyStyleDependencies(depends)
+  element.computedMap[peNone] =
+    map[peNone].applyDeclarations(element.parentElement, element, window)
   for pseudo in peBefore..peAfter:
     if map[pseudo].hasValues() or window.settings.scripting == smApp:
-      let computed = map[pseudo].applyDeclarations0(element, nil, window)
+      let computed = map[pseudo].applyDeclarations(element, nil, window)
       element.computedMap[pseudo] = computed
 
-type CascadeFrame = object
-  styledParent: StyledNode
-  child: Node
-  pseudo: PseudoElement
-  cachedChild: StyledNode
-  cachedChildren: seq[StyledNode]
-
-proc getAuthorSheets(document: Document): seq[CSSStylesheet] =
-  var author: seq[CSSStylesheet] = @[]
-  for sheet in document.sheets():
-    author.add(sheet.applyMediaQuery(document.window))
-  return author
-
-proc applyRulesFrameValid(frame: var CascadeFrame): StyledNode =
-  let styledParent = frame.styledParent
-  let cachedChild = frame.cachedChild
-  # Pseudo elements can't have invalid children.
-  if cachedChild.t == stElement and cachedChild.pseudo == peNone:
-    # Refresh child nodes:
-    # * move old seq to a temporary location in frame
-    # * create new seq, assuming capacity == len of the previous pass
-    frame.cachedChildren = move(cachedChild.children)
-    cachedChild.children = newSeqOfCap[StyledNode](frame.cachedChildren.len)
-  if styledParent != nil:
-    styledParent.children.add(cachedChild)
-  return cachedChild
-
-proc applyRulesFrameInvalid(frame: CascadeFrame; ua, user: CSSStylesheet;
-    author: seq[CSSStylesheet]; window: Window): StyledNode =
-  let pseudo = frame.pseudo
-  let styledParent = frame.styledParent
-  let child = frame.child
-  case pseudo
-  of peNone: # not a pseudo-element, but a real one
-    assert child != nil
-    if child of Element:
-      let element = Element(child)
-      let styledChild = newStyledElement(element)
-      if styledParent == nil: # root element
-        styledChild.applyDeclarations(nil, window, ua, user, author)
-      else:
-        styledParent.children.add(styledChild)
-        styledChild.applyDeclarations(styledParent.element, window, ua, user,
-          author)
-      return styledChild
-    elif child of Text:
-      let text = Text(child)
-      let styledChild = styledParent.newStyledText(text)
-      styledParent.children.add(styledChild)
-      return styledChild
-  of peBefore, peAfter:
-    let parent = styledParent.element
-    if parent.computedMap[pseudo] != nil and
-        parent.computedMap[pseudo]{"content"}.len > 0:
-      let styledPseudo = styledParent.newStyledElement(pseudo)
-      for content in parent.computedMap[pseudo]{"content"}:
-        let child = styledPseudo.newStyledReplacement(content, peNone)
-        styledPseudo.children.add(child)
-      styledParent.children.add(styledPseudo)
-  of peInputText:
-    let s = HTMLInputElement(styledParent.element).inputString()
-    if s.len > 0:
-      let content = styledParent.element.document.newText(s)
-      let styledText = styledParent.newStyledText(content)
-      # Note: some pseudo-elements (like input text) generate text nodes
-      # directly, so we have to cache them like this.
-      styledText.pseudo = pseudo
-      styledParent.children.add(styledText)
-  of peTextareaText:
-    let s = HTMLTextAreaElement(styledParent.element).textAreaString()
-    if s.len > 0:
-      let content = styledParent.element.document.newText(s)
-      let styledText = styledParent.newStyledText(content)
-      styledText.pseudo = pseudo
-      styledParent.children.add(styledText)
-  of peImage:
-    let content = CSSContent(
-      t: ContentImage,
-      bmp: HTMLImageElement(styledParent.element).bitmap
-    )
-    let styledText = styledParent.newStyledReplacement(content, pseudo)
-    styledParent.children.add(styledText)
-  of peSVG:
-    let content = CSSContent(
-      t: ContentImage,
-      bmp: SVGSVGElement(styledParent.element).bitmap
-    )
-    let styledText = styledParent.newStyledReplacement(content, pseudo)
-    styledParent.children.add(styledText)
-  of peCanvas:
-    let bmp = HTMLCanvasElement(styledParent.element).bitmap
-    if bmp != nil and bmp.cacheId != 0:
-      let content = CSSContent(
-        t: ContentImage,
-        bmp: bmp
-      )
-      let styledText = styledParent.newStyledReplacement(content, pseudo)
-      styledParent.children.add(styledText)
-  of peVideo:
-    let content = CSSContent(t: ContentVideo)
-    let styledText = styledParent.newStyledReplacement(content, pseudo)
-    styledParent.children.add(styledText)
-  of peAudio:
-    let content = CSSContent(t: ContentAudio)
-    let styledText = styledParent.newStyledReplacement(content, pseudo)
-    styledParent.children.add(styledText)
-  of peIFrame:
-    let content = CSSContent(t: ContentIFrame)
-    let styledText = styledParent.newStyledReplacement(content, pseudo)
-    styledParent.children.add(styledText)
-  of peNewline:
-    let content = CSSContent(t: ContentNewline)
-    let styledText = styledParent.newStyledReplacement(content, pseudo)
-    styledParent.children.add(styledText)
-  return nil
-
-proc stackAppend(styledStack: var seq[CascadeFrame]; frame: CascadeFrame;
-    styledParent: StyledNode; child: Element; i: var int) =
-  var cached: StyledNode = nil
-  if frame.cachedChildren.len > 0:
-    for j in countdown(i, 0):
-      let it = frame.cachedChildren[j]
-      if it.t == stElement and it.pseudo == peNone and it.element == child:
-        i = j - 1
-        cached = it
-        break
-  styledStack.add(CascadeFrame(
-    styledParent: styledParent,
-    child: child,
-    pseudo: peNone,
-    cachedChild: cached
-  ))
-
-proc stackAppend(styledStack: var seq[CascadeFrame]; frame: CascadeFrame;
-    styledParent: StyledNode; child: Text; i: var int) =
-  var cached: StyledNode = nil
-  if frame.cachedChildren.len > 0:
-    for j in countdown(i, 0):
-      let it = frame.cachedChildren[j]
-      if it.t == stText and it.text == child:
-        i = j - 1
-        cached = it
-        break
-  styledStack.add(CascadeFrame(
-    styledParent: styledParent,
-    child: child,
-    pseudo: peNone,
-    cachedChild: cached
-  ))
-
-proc stackAppend(styledStack: var seq[CascadeFrame]; frame: CascadeFrame;
-    styledParent: StyledNode; pseudo: PseudoElement; i: var int) =
-  # Can't check for cachedChildren.len here, because we assume that we only have
-  # cached pseudo elems when the parent is also cached.
-  if frame.cachedChild != nil:
-    var cached: StyledNode = nil
-    for j in countdown(i, 0):
-      let it = frame.cachedChildren[j]
-      if it.pseudo == pseudo:
-        cached = it
-        i = j - 1
-        break
-    # When calculating pseudo-element rules, their dependencies are added
-    # to their parent's dependency list; so invalidating a pseudo-element
-    # invalidates its parent too, which in turn automatically rebuilds
-    # the pseudo-element.
-    # In other words, we can just do this:
-    if cached != nil:
-      styledStack.add(CascadeFrame(
-        styledParent: styledParent,
-        pseudo: pseudo,
-        cachedChild: cached
-      ))
-  else:
-    styledStack.add(CascadeFrame(
-      styledParent: styledParent,
-      pseudo: pseudo,
-      cachedChild: nil
-    ))
-
-# Append children to styledChild.
-proc appendChildren(styledStack: var seq[CascadeFrame]; frame: CascadeFrame;
-    styledChild: StyledNode) =
-  # i points to the child currently being inspected.
-  var idx = frame.cachedChildren.len - 1
-  let element = styledChild.element
-  # reset invalid flag here to avoid a type conversion above
-  element.invalid = false
-  styledStack.stackAppend(frame, styledChild, peAfter, idx)
-  case element.tagType
-  of TAG_TEXTAREA:
-    styledStack.stackAppend(frame, styledChild, peTextareaText, idx)
-  of TAG_IMG: styledStack.stackAppend(frame, styledChild, peImage, idx)
-  of TAG_VIDEO: styledStack.stackAppend(frame, styledChild, peVideo, idx)
-  of TAG_AUDIO: styledStack.stackAppend(frame, styledChild, peAudio, idx)
-  of TAG_BR: styledStack.stackAppend(frame, styledChild, peNewline, idx)
-  of TAG_CANVAS: styledStack.stackAppend(frame, styledChild, peCanvas, idx)
-  of TAG_IFRAME: styledStack.stackAppend(frame, styledChild, peIFrame, idx)
-  elif element.tagType(Namespace.SVG) == TAG_SVG:
-    styledStack.stackAppend(frame, styledChild, peSVG, idx)
-  else:
-    for i in countdown(element.childList.high, 0):
-      let child = element.childList[i]
-      if child of Element:
-        styledStack.stackAppend(frame, styledChild, Element(child), idx)
-      elif child of Text:
-        styledStack.stackAppend(frame, styledChild, Text(child), idx)
-    if element.tagType == TAG_INPUT:
-      styledStack.stackAppend(frame, styledChild, peInputText, idx)
-  styledStack.stackAppend(frame, styledChild, peBefore, idx)
-
-# Builds a StyledNode tree, optionally based on a previously cached version.
-proc applyRules(document: Document; ua, user: CSSStylesheet;
-    cachedTree: StyledNode): StyledNode =
-  let html = document.documentElement
-  if html == nil:
+# Abstraction over the DOM to pretend that elements, text, replaced and
+# pseudo-elements are derived from the same type.
+type
+  StyledType* = enum
+    stElement, stText, stReplacement
+
+  StyledNode* = object
+    element*: Element
+    pseudo*: PseudoElement
+    case t*: StyledType
+    of stText:
+      text*: CharacterData
+    of stElement:
+      discard
+    of stReplacement:
+      # replaced elements: quotes, images, or (TODO) markers
+      content*: CSSContent
+
+when defined(debug):
+  func `$`*(node: StyledNode): string =
+    case node.t
+    of stText:
+      return "#text " & node.text.data
+    of stElement:
+      if node.pseudo != peNone:
+        return $node.element.tagType & "::" & $node.pseudo
+      return $node.element
+    of stReplacement:
+      return "#replacement"
+
+# Defined here so it isn't accidentally used in dom.
+#TODO it may be better to do it in dom anyway, so we can cache it...
+func newCharacterData*(data: sink string): CharacterData =
+  return CharacterData(data: data)
+
+template computed*(styledNode: StyledNode): CSSValues =
+  styledNode.element.computedMap[styledNode.pseudo]
+
+proc initStyledElement*(element: Element): StyledNode =
+  if element.computed == nil:
+    element.applyStyle()
+  return StyledNode(t: stElement, element: element)
+
+proc initStyledReplacement(parent: Element; content: sink CSSContent):
+    StyledNode =
+  return StyledNode(t: stReplacement, element: parent, content: content)
+
+proc initStyledImage(parent: Element; bmp: NetworkBitmap): StyledNode =
+  return initStyledReplacement(parent, CSSContent(t: ContentImage, bmp: bmp))
+
+proc initStyledPseudo(parent: Element; pseudo: PseudoElement): StyledNode =
+  return StyledNode(t: stElement, pseudo: pseudo, element: parent)
+
+proc initStyledText(parent: Element; text: CharacterData): StyledNode =
+  return StyledNode(t: stText, element: parent, text: text)
+
+proc initStyledText(parent: Element; s: sink string): StyledNode =
+  return initStyledText(parent, newCharacterData(s))
+
+# Many yields; we use a closure iterator to avoid bloating the code.
+iterator children*(styledNode: StyledNode): StyledNode {.closure.} =
+  if styledNode.t != stElement:
     return
-  let author = document.getAuthorSheets()
-  var styledStack = @[CascadeFrame(
-    child: html,
-    pseudo: peNone,
-    cachedChild: cachedTree
-  )]
-  var root: StyledNode = nil
-  var toReset: seq[Element] = @[]
-  while styledStack.len > 0:
-    var frame = styledStack.pop()
-    let styledParent = frame.styledParent
-    let valid = frame.cachedChild != nil and frame.cachedChild.isValid(toReset)
-    let styledChild = if valid:
-      frame.applyRulesFrameValid()
+  if styledNode.pseudo == peNone:
+    let parent = styledNode.element
+    if parent.computedMap[peBefore] != nil and
+        parent.computedMap[peBefore]{"content"}.len > 0:
+      yield initStyledPseudo(parent, peBefore)
+    case parent.tagType
+    of TAG_INPUT:
+      #TODO cache (just put value in a CharacterData)
+      let s = HTMLInputElement(parent).inputString()
+      if s.len > 0:
+        yield initStyledText(parent, s)
+    of TAG_TEXTAREA:
+      #TODO cache (do the same as with input, and add borders in render)
+      yield initStyledText(parent, HTMLTextAreaElement(parent).textAreaString())
+    of TAG_IMG: yield initStyledImage(parent, HTMLImageElement(parent).bitmap)
+    of TAG_CANVAS:
+      yield initStyledImage(parent, HTMLImageElement(parent).bitmap)
+    of TAG_VIDEO: yield initStyledText(parent, "[video]")
+    of TAG_AUDIO: yield initStyledText(parent, "[audio]")
+    of TAG_BR:
+      yield initStyledReplacement(parent, CSSContent(t: ContentNewline))
+    of TAG_IFRAME: yield initStyledText(parent, "[iframe]")
+    elif parent.tagType(Namespace.SVG) == TAG_SVG:
+      yield initStyledImage(parent, SVGSVGElement(parent).bitmap)
     else:
-      # From here on, computed values of this node's children are invalid
-      # because of property inheritance.
-      frame.cachedChild = nil
-      frame.applyRulesFrameInvalid(ua, user, author, document.window)
-    if styledChild != nil:
-      if styledParent == nil:
-        # Root element
-        root = styledChild
-      if styledChild.t == stElement and styledChild.pseudo == peNone:
-        # note: following resets styledChild.node's invalid flag
-        styledStack.appendChildren(frame, styledChild)
-  for element in toReset:
-    element.invalidDeps = {}
-  return root
-
-proc applyStylesheets*(document: Document; uass, userss: CSSStylesheet;
-    previousStyled: StyledNode): StyledNode =
-  let uass = uass.applyMediaQuery(document.window)
-  let userss = userss.applyMediaQuery(document.window)
-  return document.applyRules(uass, userss, previousStyled)
+      for it in parent.childList:
+        if it of Element:
+          yield initStyledElement(Element(it))
+        elif it of Text:
+          yield initStyledText(parent, Text(it))
+    if parent.computedMap[peAfter] != nil and
+        parent.computedMap[peAfter]{"content"}.len > 0:
+      yield initStyledPseudo(parent, peAfter)
+  else:
+    let parent = styledNode.element
+    for content in parent.computedMap[styledNode.pseudo]{"content"}:
+      yield parent.initStyledReplacement(content)
diff --git a/src/css/cssvalues.nim b/src/css/cssvalues.nim
index 7da9bbc4..537f856d 100644
--- a/src/css/cssvalues.nim
+++ b/src/css/cssvalues.nim
@@ -266,9 +266,8 @@ type
     BorderCollapseCollapse = "collapse"
 
   CSSContentType* = enum
-    ContentNone, ContentString, ContentOpenQuote, ContentCloseQuote,
-    ContentNoOpenQuote, ContentNoCloseQuote, ContentImage, ContentVideo,
-    ContentAudio, ContentNewline, ContentIFrame
+    ContentString, ContentOpenQuote, ContentCloseQuote, ContentNoOpenQuote,
+    ContentNoCloseQuote, ContentImage, ContentNewline
 
   CSSFloat* = enum
     FloatNone = "none"
diff --git a/src/css/layout.nim b/src/css/layout.nim
index de255afa..471c7364 100644
--- a/src/css/layout.nim
+++ b/src/css/layout.nim
@@ -2,9 +2,9 @@ import std/algorithm
 import std/math
 
 import css/box
+import css/cascade
 import css/cssvalues
 import css/lunit
-import css/stylednode
 import html/dom
 import types/bitmap
 import types/winattrs
@@ -49,17 +49,10 @@ type
     myRootProperties: CSSValues
     # placeholder text data
     imgText: CharacterData
-    audioText: CharacterData
-    videoText: CharacterData
-    iframeText: CharacterData
     luctx: LUContext
 
 const DefaultSpan = Span(start: 0, send: LUnit.high)
 
-# Defined here so it isn't accidentally used in dom.
-func newCharacterData(data: sink string): CharacterData =
-  return CharacterData(data: data)
-
 func minWidth(sizes: ResolvedSizes): LUnit =
   return sizes.bounds.a[dtHorizontal].start
 
@@ -3158,7 +3151,6 @@ proc buildFromElem(ctx: var BlockBuilderContext; styledNode: StyledNode;
 proc buildReplacement(ctx: var BlockBuilderContext; child: StyledNode;
     parent: Element; computed: CSSValues) =
   case child.content.t
-  of ContentNone: assert false # unreachable for `content'
   of ContentOpenQuote:
     let quotes = parent.computed{"quotes"}
     let s = if quotes == nil:
@@ -3199,12 +3191,6 @@ proc buildReplacement(ctx: var BlockBuilderContext; child: StyledNode;
       ))
     else:
       ctx.pushInlineText(computed, parent, ctx.lctx.imgText)
-  of ContentVideo:
-    ctx.pushInlineText(computed, parent, ctx.lctx.videoText)
-  of ContentAudio:
-    ctx.pushInlineText(computed, parent, ctx.lctx.audioText)
-  of ContentIFrame:
-    ctx.pushInlineText(computed, parent, ctx.lctx.iframeText)
   of ContentNewline:
     ctx.pushInline(InlineBox(
       t: ibtNewline,
@@ -3446,9 +3432,6 @@ proc layout*(root: StyledNode; attrsp: ptr WindowAttributes): BlockBox =
     positioned: @[PositionedItem(), PositionedItem()],
     myRootProperties: rootProperties(),
     imgText: newCharacterData("[img]"),
-    videoText: newCharacterData("[video]"),
-    audioText: newCharacterData("[audio]"),
-    iframeText: newCharacterData("[iframe]"),
     luctx: LUContext()
   )
   let box = BlockBox(computed: root.computed, node: root.element)
diff --git a/src/css/match.nim b/src/css/match.nim
index c23ac8da..737dd1d6 100644
--- a/src/css/match.nim
+++ b/src/css/match.nim
@@ -216,7 +216,7 @@ func matches*(element: Element; cxsel: ComplexSelector;
     depends: var DependencyInfo): bool =
   var e = element
   var pmatch = mtTrue
-  var mdepends = DependencyInfo()
+  var mdepends = DependencyInfo.default
   for i in countdown(cxsel.high, 0):
     var match = mtFalse
     case cxsel[i].ct
diff --git a/src/css/selectorparser.nim b/src/css/selectorparser.nim
index 026fe140..70da9119 100644
--- a/src/css/selectorparser.nim
+++ b/src/css/selectorparser.nim
@@ -13,16 +13,6 @@ type
     peNone = "-cha-none"
     peBefore = "before"
     peAfter = "after"
-    # internal
-    peInputText = "-cha-input-text"
-    peTextareaText = "-cha-textarea-text"
-    peImage = "-cha-image"
-    peNewline = "-cha-newline"
-    peVideo = "-cha-video"
-    peAudio = "-cha-audio"
-    peCanvas = "-cha-canvas"
-    peSVG = "-cha-svg"
-    peIFrame = "-cha-iframe"
 
   PseudoClass* = enum
     pcFirstChild = "first-child"
diff --git a/src/css/stylednode.nim b/src/css/stylednode.nim
deleted file mode 100644
index 5a123d9f..00000000
--- a/src/css/stylednode.nim
+++ /dev/null
@@ -1,72 +0,0 @@
-import css/cssvalues
-import css/selectorparser
-import html/dom
-
-# Container to hold a style and a node.
-#TODO: maintaining a separate tree for styles is inefficient, and at
-# this point, most of it has been moved to the DOM anyway.
-#
-# The only purpose it has left is to arrange text, element and
-# pseudo-element nodes into a single seq, but this should be done
-# with an iterator instead.
-
-type
-  StyledType* = enum
-    stElement, stText, stReplacement
-
-  StyledNode* = ref object
-    element*: Element
-    pseudo*: PseudoElement
-    case t*: StyledType
-    of stText:
-      text*: CharacterData
-    of stElement:
-      children*: seq[StyledNode]
-    of stReplacement:
-      # replaced elements: quotes, or (TODO) markers, images
-      content*: CSSContent
-
-when defined(debug):
-  func `$`*(node: StyledNode): string =
-    if node == nil:
-      return "nil"
-    case node.t
-    of stText:
-      return "#text " & node.text.data
-    of stElement:
-      if node.pseudo != peNone:
-        return $node.element.tagType & "::" & $node.pseudo
-      return $node.element
-    of stReplacement:
-      return "#replacement"
-
-template computed*(styledNode: StyledNode): CSSValues =
-  styledNode.element.computedMap[styledNode.pseudo]
-
-proc isValid*(styledNode: StyledNode; toReset: var seq[Element]): bool =
-  if styledNode.t in {stText, stReplacement} or styledNode.pseudo != peNone:
-    # pseudo elements do not have selector dependencies
-    return true
-  return styledNode.element.isValid(toReset)
-
-func newStyledElement*(element: Element): StyledNode =
-  return StyledNode(t: stElement, element: element)
-
-func newStyledElement*(parent: StyledNode; pseudo: PseudoElement): StyledNode =
-  return StyledNode(
-    t: stElement,
-    pseudo: pseudo,
-    element: parent.element
-  )
-
-func newStyledText*(parent: StyledNode; text: Text): StyledNode =
-  return StyledNode(t: stText, text: text, element: parent.element)
-
-func newStyledReplacement*(parent: StyledNode; content: sink CSSContent;
-    pseudo: PseudoElement): StyledNode =
-  return StyledNode(
-    t: stReplacement,
-    element: parent.element,
-    content: content,
-    pseudo: pseudo
-  )