about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/css/cascade.nim29
-rw-r--r--src/css/parser.nim10
-rw-r--r--src/css/selparser.nim11
-rw-r--r--src/css/sheet.nim46
-rw-r--r--src/html/dom.nim4
-rw-r--r--src/html/parser.nim4
-rw-r--r--src/io/buffer.nim4
-rw-r--r--src/layout/engine.nim2
8 files changed, 74 insertions, 36 deletions
diff --git a/src/css/cascade.nim b/src/css/cascade.nim
index cd952487..56c3dc09 100644
--- a/src/css/cascade.nim
+++ b/src/css/cascade.nim
@@ -6,6 +6,7 @@ import algorithm
 import css/select
 import css/selparser
 import css/parser
+import css/sheet
 import css/values
 import html/dom
 import html/tags
@@ -34,14 +35,16 @@ proc applyProperty(elem: Element, d: CSSDeclaration, pseudo: PseudoElem) =
   elem.cssapplied = true
   elem.rendered = false
 
-func calcRules(elem: Element, rules: ParsedStylesheet): RuleList =
+func calcRules(elem: Element, rules: CSSStylesheet): RuleList =
   var tosorts: array[low(PseudoElem)..high(PseudoElem), seq[tuple[s:int,b:CSSSimpleBlock]]]
   for rule in rules:
-    for sel in rule.sels:
-      let match = elem.selectorsMatch(sel)
-      if match.success:
-        let spec = getSpecificity(sel)
-        tosorts[match.pseudo].add((spec,rule.oblock))
+    if rule of CSSRuleDef:
+      let rule = CSSRuleDef(rule)
+      for sel in rule.sels:
+        let match = elem.selectorsMatch(sel)
+        if match.success:
+          let spec = getSpecificity(sel)
+          tosorts[match.pseudo].add((spec,rule.oblock))
 
   for i in low(PseudoElem)..high(PseudoElem):
     tosorts[i].sort((x, y) => cmp(x.s,y.s))
@@ -86,18 +89,18 @@ proc applyRules(element: Element, ua, user, author: RuleList, pseudo: PseudoElem
   for rule in ares.important:
     element.applyProperty(rule, pseudo)
 
-proc applyRules*(document: Document, ua, user: ParsedStylesheet) =
+proc applyRules*(document: Document, ua, user: CSSStylesheet) =
   var stack: seq[Element]
 
-  var embedded_rules: seq[ParsedStylesheet]
+  var embedded_rules: seq[CSSStylesheet]
 
   stack.add(document.head)
-  var rules_head: ParsedStylesheet
+  var rules_head: CSSStylesheet
 
   for child in document.head.children:
     if child.tagType == TAG_STYLE:
       let style = HTMLStyleElement(child)
-      rules_head.add(style.stylesheet)
+      rules_head.add(style.sheet)
 
   if rules_head.len > 0:
     embedded_rules.add(rules_head)
@@ -111,11 +114,11 @@ proc applyRules*(document: Document, ua, user: ParsedStylesheet) =
   while stack.len > 0:
     let elem = stack.pop()
 
-    var rules_local: ParsedStylesheet
+    var rules_local: CSSStylesheet
     for child in document.head.children:
       if child.tagType == TAG_STYLE:
         let style = HTMLStyleElement(child)
-        rules_local.add(style.stylesheet)
+        rules_local.add(style.sheet)
 
     if rules_local.len > 0:
       embedded_rules.add(rules_local)
@@ -143,7 +146,7 @@ proc applyRules*(document: Document, ua, user: ParsedStylesheet) =
     if rules_local.len > 0:
       discard embedded_rules.pop()
 
-proc applyStylesheets*(document: Document, uass, userss: ParsedStylesheet) =
+proc applyStylesheets*(document: Document, uass, userss: CSSStylesheet) =
   document.applyRules(uass, userss)
 
 proc refreshStyle*(elem: Element) =
diff --git a/src/css/parser.nim b/src/css/parser.nim
index b594abc3..5bd2cf8b 100644
--- a/src/css/parser.nim
+++ b/src/css/parser.nim
@@ -69,7 +69,7 @@ type
     token*: CSSToken
     value*: seq[CSSComponentValue]
 
-  CSSStylesheet* = object
+  CSSRawStylesheet* = object
     value*: seq[CSSRule]
 
   SyntaxError = object of ValueError
@@ -581,11 +581,11 @@ proc consumeListOfRules(state: var CSSParseState): seq[CSSRule] =
       if q.isSome:
         result.add(q.get)
 
-proc parseStylesheet(state: var CSSParseState): CSSStylesheet =
+proc parseStylesheet(state: var CSSParseState): CSSRawStylesheet =
   state.top_level = true
   result.value.add(state.consumeListOfRules())
 
-proc parseStylesheet(inputStream: Stream): CSSStylesheet =
+proc parseStylesheet(inputStream: Stream): CSSRawStylesheet =
   var state = CSSParseState()
   state.tokens = tokenizeCSS(inputStream)
   return state.parseStylesheet()
@@ -748,9 +748,9 @@ func `$`*(c: CSSComponentValue): string =
     of CSS_LBRACKET_TOKEN: result &= "]"
     else: discard
 
-proc parseCSS*(inputStream: Stream): CSSStylesheet =
+proc parseCSS*(inputStream: Stream): CSSRawStylesheet =
   if inputStream.atEnd():
-    return CSSStylesheet()
+    return CSSRawStylesheet()
   return inputstream.parseStylesheet()
 
 proc debugparseCSS*(inputStream: Stream) =
diff --git a/src/css/selparser.nim b/src/css/selparser.nim
index 0c1655aa..67f53b42 100644
--- a/src/css/selparser.nim
+++ b/src/css/selparser.nim
@@ -1,5 +1,4 @@
 import unicode
-import streams
 
 import css/parser
 import html/tags
@@ -57,9 +56,6 @@ type
     sels*: seq[Selector]
     parent*: SelectorList
 
-  ParsedRule* = tuple[sels: seq[SelectorList], oblock: CSSSimpleBlock]
-  ParsedStylesheet* = seq[ParsedRule]
-
 proc add*(sellist: SelectorList, sel: Selector) = sellist.sels.add(sel)
 proc add*(sellist: SelectorList, sels: SelectorList) = sellist.sels.add(sels.sels)
 proc setLen*(sellist: SelectorList, i: int) = sellist.sels.setLen(i)
@@ -301,10 +297,3 @@ func parseSelectors*(cvals: seq[CSSComponentValue]): seq[SelectorList] =
     state.selectors[^1].add(state.combinator)
     state.combinator = nil
   return state.selectors
-
-#TODO this is pretty dumb
-proc parseStylesheet*(s: Stream): ParsedStylesheet =
-  for v in parseCSS(s).value:
-    let sels = parseSelectors(v.prelude)
-    if sels.len > 1 or sels[^1].len > 0:
-      result.add((sels, v.oblock))
diff --git a/src/css/sheet.nim b/src/css/sheet.nim
new file mode 100644
index 00000000..4db068f3
--- /dev/null
+++ b/src/css/sheet.nim
@@ -0,0 +1,46 @@
+import streams
+
+import css/parser
+import css/selparser
+
+type
+  CSSRuleBase* = object of RootObj
+
+  CSSRuleDef* = object of CSSRuleBase
+    sels*: seq[SelectorList]
+    oblock*: CSSSimpleBlock
+
+  CSSConditionalDef* = object of CSSRuleBase
+    rules*: CSSSimpleBlock
+    nested*: seq[CSSConditionalDef]
+
+  CSSMediaQueryDef = object of CSSConditionalDef
+    query*: string
+
+  CSSStylesheet* = seq[CSSRuleDef]
+
+proc addRule(stylesheet: var CSSStylesheet, rule: CSSRule) =
+  let sels = parseSelectors(rule.prelude)
+  if sels.len > 1 or sels[^1].len > 0:
+    let r = CSSRuleDef(sels: sels, oblock: rule.oblock)
+    stylesheet.add(r)
+
+proc parseAtRule(atrule: CSSAtRule): CSSConditionalDef =
+  for v in atrule.oblock.value:
+    if v of CSSRule:
+      if v of CSSAtRule:
+        #let atrule = CSSAtRule(v)
+        discard
+      else:
+        discard
+        #let rule = CSSRule(v)
+        #let sels = parseSelectors(rule.prelude)
+        #result.rules.add(CSSRule)
+
+proc parseStylesheet*(s: Stream): CSSStylesheet =
+  for v in parseCSS(s).value:
+    if v of CSSAtRule:
+      discard
+      #result.add(CSSAtRule(v).parseAtRule())
+    else:
+      result.addRule(v)
diff --git a/src/html/dom.nim b/src/html/dom.nim
index f9a4cfea..85a48174 100644
--- a/src/html/dom.nim
+++ b/src/html/dom.nim
@@ -4,7 +4,7 @@ import options
 import strutils
 
 import css/values
-import css/selparser
+import css/sheet
 import html/tags
 
 type
@@ -114,7 +114,7 @@ type
     ordinalvalue*: int
 
   HTMLStyleElement* = ref object of HTMLElement
-    stylesheet*: ParsedStylesheet
+    sheet*: CSSStylesheet
 
 iterator textNodes*(node: Node): Text {.inline.} =
   for node in node.childNodes:
diff --git a/src/html/parser.nim b/src/html/parser.nim
index c3e12300..8809e392 100644
--- a/src/html/parser.nim
+++ b/src/html/parser.nim
@@ -10,7 +10,7 @@ import utils/radixtree
 import html/dom
 import html/entity
 import html/tags
-import css/selparser
+import css/sheet
 
 type
   HTMLParseState = object
@@ -325,7 +325,7 @@ proc processDocumentEndElement(state: var HTMLParseState, tag: DOMParsedTag) =
       var str = ""
       for child in style.textNodes:
         str &= child.data
-      style.stylesheet = newStringStream(str).parseStylesheet()
+      style.sheet = newStringStream(str).parseStylesheet()
     else: discard
     processDocumentEndNode(state)
 
diff --git a/src/io/buffer.nim b/src/io/buffer.nim
index 9edc0738..62c68486 100644
--- a/src/io/buffer.nim
+++ b/src/io/buffer.nim
@@ -6,7 +6,7 @@ import streams
 
 import css/values
 import css/cascade
-import css/selparser
+import css/sheet
 import utils/twtstr
 import html/dom
 import html/tags
@@ -728,7 +728,7 @@ let ua_stylesheet = newStringStream(css).parseStylesheet()
 
 #TODO refactor
 var ss_init = false
-var user_stylesheet: ParsedStylesheet
+var user_stylesheet: CSSStylesheet
 proc renderDocument*(buffer: Buffer) =
   buffer.clearText()
 
diff --git a/src/layout/engine.nim b/src/layout/engine.nim
index 7ace19d1..7628416d 100644
--- a/src/layout/engine.nim
+++ b/src/layout/engine.nim
@@ -353,7 +353,7 @@ proc add(state: var LayoutState, parent: CSSBox, box: CSSInlineBox) =
   parent.children.add(box)
 
 proc add(state: var LayoutState, parent: CSSBox, box: CSSInlineBlockBox) =
-  parent.icontext.fromx = box.icontext.fromx
+  parent.icontext.fromx = max(box.icontext.fromx, box.bcontext.width)
   parent.icontext.fromx += box.cssvalues{"margin-right"}.cells_w(state, parent.bcontext.width)
   parent.icontext.conty = box.icontext.conty