about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2021-12-13 14:42:45 +0100
committerbptato <nincsnevem662@gmail.com>2021-12-13 14:42:45 +0100
commit98b7ef37199278a57304cb1a8f73b4de1e21f432 (patch)
tree036750b5de0e430a943c01ec632e35fab64cd890
parent332dedce2ba760d942fea337a285456427828fe4 (diff)
downloadchawan-98b7ef37199278a57304cb1a8f73b4de1e21f432.tar.gz
Support height, fix margin
-rw-r--r--src/css/style.nim22
-rw-r--r--src/css/values.nim10
-rw-r--r--src/layout/engine.nim22
-rw-r--r--src/types/enums.nim3
4 files changed, 43 insertions, 14 deletions
diff --git a/src/css/style.nim b/src/css/style.nim
index 258cf438..e2bf2347 100644
--- a/src/css/style.nim
+++ b/src/css/style.nim
@@ -192,8 +192,18 @@ proc querySelector*(document: Document, q: string): seq[Element] =
   for sel in selectors:
     result.add(document.selectElems(sel))
 
-proc applyProperty(elem: Element, decl: CSSDeclaration, pseudo: PseudoElem) =
-  let cval = getComputedValue(decl, elem.cssvalues)
+proc applyProperty(elem: Element, s: CSSSpecifiedValue, pseudo: PseudoElem) =
+  let cval = getComputedValue(s, elem.cssvalues)
+  if cval.t == PROPERTY_MARGIN:
+    let left = CSSSpecifiedValue(t: PROPERTY_MARGIN_LEFT, v: VALUE_LENGTH, length: cval.length, globalValue: s.globalValue)
+    let right = CSSSpecifiedValue(t: PROPERTY_MARGIN_RIGHT, v: VALUE_LENGTH, length: cval.length, globalValue: s.globalValue)
+    let top = CSSSpecifiedValue(t: PROPERTY_MARGIN_TOP, v: VALUE_LENGTH, length: cval.length, globalValue: s.globalValue)
+    let bottom = CSSSpecifiedValue(t: PROPERTY_MARGIN_BOTTOM, v: VALUE_LENGTH, length: cval.length, globalValue: s.globalValue)
+    elem.applyProperty(left, pseudo)
+    elem.applyProperty(right, pseudo)
+    elem.applyProperty(top, pseudo)
+    elem.applyProperty(bottom, pseudo)
+    return
   case pseudo
   of PSEUDO_NONE:
     elem.cssvalues[cval.t] = cval
@@ -212,8 +222,8 @@ type
   ParsedRule* = tuple[sels: seq[SelectorList], oblock: CSSSimpleBlock]
   ParsedStylesheet* = seq[ParsedRule]
   ApplyResult = object
-    normal: seq[tuple[e:Element,d:CSSDeclaration,p:PseudoElem]]
-    important: seq[tuple[e:Element,d:CSSDeclaration,p:PseudoElem]]
+    normal: seq[tuple[e:Element,d:CSSSpecifiedValue,p:PseudoElem]]
+    important: seq[tuple[e:Element,d:CSSSpecifiedValue,p:PseudoElem]]
 
 proc parseStylesheet*(s: Stream): ParsedStylesheet =
   for v in parseCSS(s).value:
@@ -240,9 +250,9 @@ proc applyItems*(ares: var ApplyResult, elem: Element, decls: seq[CSSParsedItem]
     if item of CSSDeclaration:
       let decl = CSSDeclaration(item)
       if decl.important:
-        ares.important.add((elem, decl, pseudo))
+        ares.important.add((elem, getSpecifiedValue(decl), pseudo))
       else:
-        ares.normal.add((elem, decl, pseudo))
+        ares.normal.add((elem, getSpecifiedValue(decl), pseudo))
 
 proc applyRules*(document: Document, pss: ParsedStylesheet, reset: bool = false): ApplyResult =
   var stack: seq[Element]
diff --git a/src/css/values.nim b/src/css/values.nim
index ea169bbb..8ad2a92a 100644
--- a/src/css/values.nim
+++ b/src/css/values.nim
@@ -44,7 +44,7 @@ type
   CSSComputedValues* = ref array[low(CSSPropertyType)..high(CSSPropertyType), CSSComputedValue]
 
   CSSSpecifiedValue* = object of CSSComputedValue
-    globalValue: CSSGlobalValueType
+    globalValue*: CSSGlobalValueType
 
   CSSValueError* = object of ValueError
 
@@ -65,6 +65,7 @@ const PropertyNames = {
   "text-decoration": PROPERTY_TEXT_DECORATION,
   "word-break": PROPERTY_WORD_BREAK,
   "width": PROPERTY_WIDTH,
+  "height": PROPERTY_HEIGHT,
 }.toTable()
 
 const ValueTypes = [
@@ -84,6 +85,7 @@ const ValueTypes = [
   PROPERTY_TEXT_DECORATION: VALUE_TEXT_DECORATION,
   PROPERTY_WORD_BREAK: VALUE_WORD_BREAK,
   PROPERTY_WIDTH: VALUE_LENGTH,
+  PROPERTY_HEIGHT: VALUE_LENGTH,
 ]
 
 const InheritedProperties = {
@@ -523,10 +525,8 @@ func getSpecifiedValue*(d: CSSDeclaration): CSSSpecifiedValue =
     of VALUE_CONTENT: result.content = cssString(d)
     of VALUE_WHITE_SPACE: result.whitespace = cssWhiteSpace(d)
     of VALUE_INTEGER:
-      case ptype
-      of PROPERTY_FONT_WEIGHT:
+      if ptype == PROPERTY_FONT_WEIGHT:
         result.integer = cssFontWeight(d)
-      else: discard #???
     of VALUE_TEXT_DECORATION: result.textdecoration = cssTextDecoration(d)
     of VALUE_WORD_BREAK: result.wordbreak = cssWordBreak(d)
     of VALUE_NONE: discard
@@ -545,7 +545,7 @@ func getInitialColor(t: CSSPropertyType): CSSColor =
 
 func getInitialLength(t: CSSPropertyType): CSSLength =
   case t
-  of PROPERTY_WIDTH:
+  of PROPERTY_WIDTH, PROPERTY_HEIGHT:
     return CSSLength(auto: true)
   else:
     return CSSLength()
diff --git a/src/layout/engine.nim b/src/layout/engine.nim
index 9b139d77..614fd332 100644
--- a/src/layout/engine.nim
+++ b/src/layout/engine.nim
@@ -8,7 +8,6 @@ import utils/twtstr
 
 func newInlineContext*(box: CSSBox): InlineContext =
   new(result)
-  result.fromx = box.x
   result.whitespace = true
   result.ws_initial = true
 
@@ -28,6 +27,7 @@ proc flushLines(box: CSSBox) =
 func newBlockBox(state: var LayoutState, parent: CSSBox, vals: CSSComputedValues): CSSBlockBox =
   new(result)
   result.x = parent.x
+  result.x += vals[PROPERTY_MARGIN_LEFT].length.cells()
   result.bcontext = newBlockContext()
 
   parent.flushLines()
@@ -50,6 +50,7 @@ func newBlockBox(state: var LayoutState, parent: CSSBox, vals: CSSComputedValues
 
   result.icontext = newInlineContext(parent)
   result.icontext.fromy = result.y
+  result.icontext.fromx = result.x
   result.cssvalues = vals
 
 func newInlineBox*(parent: CSSBox, vals: CSSComputedValues): CSSInlineBox =
@@ -62,6 +63,7 @@ func newInlineBox*(parent: CSSBox, vals: CSSComputedValues): CSSInlineBox =
   result.icontext = parent.icontext
   result.bcontext = parent.bcontext
   result.cssvalues = vals
+  result.icontext.fromx += vals[PROPERTY_MARGIN_LEFT].length.cells()
 
 type InlineState = object
   ibox: CSSInlineBox
@@ -176,7 +178,11 @@ proc processInlineBox(lstate: var LayoutState, parent: CSSBox, str: string): CSS
     state.ibox = CSSInlineBox(parent)
     use_parent = true
   else:
-    state.ibox = newInlineBox(parent, parent.cssvalues)
+    # TODO TODO TODO I highly doubt this is correct but it's the only way it
+    # makes sense...
+    var inherit: CSSComputedValues
+    inherit.inheritProperties(parent.cssvalues)
+    state.ibox = newInlineBox(parent, inherit)
 
   if str.len == 0:
     return
@@ -266,8 +272,20 @@ proc add(state: var LayoutState, parent: CSSBox, box: CSSBox) =
     parent.bcontext.margin_todo = max(parent.bcontext.margin_todo - box.bcontext.margin_done, 0)
 
     #eprint "END", CSSBlockBox(box).tag, box.icontext.fromy
+  elif box of CSSInlineBox:
+    parent.icontext.fromx += box.cssvalues[PROPERTY_MARGIN_RIGHT].length.cells()
+
+  let pheight = box.cssvalues[PROPERTY_HEIGHT]
   parent.height += box.height
   parent.icontext.fromy = box.icontext.fromy
+
+  if not pheight.length.auto:
+    let max = pheight.length.cells()
+    let diff = box.height - max
+    if diff > 0:
+      parent.height -= diff
+      parent.icontext.fromy -= diff
+
   parent.children.add(box)
 
 func isBlock(node: Node): bool =
diff --git a/src/types/enums.nim b/src/types/enums.nim
index 9aacfc21..aeb53567 100644
--- a/src/types/enums.nim
+++ b/src/types/enums.nim
@@ -60,7 +60,8 @@ type
     PROPERTY_MARGIN_TOP, PROPERTY_MARGIN_LEFT, PROPERTY_MARGIN_RIGHT,
     PROPERTY_MARGIN_BOTTOM, PROPERTY_FONT_STYLE, PROPERTY_DISPLAY,
     PROPERTY_CONTENT, PROPERTY_WHITE_SPACE, PROPERTY_FONT_WEIGHT,
-    PROPERTY_TEXT_DECORATION, PROPERTY_WORD_BREAK, PROPERTY_WIDTH
+    PROPERTY_TEXT_DECORATION, PROPERTY_WORD_BREAK, PROPERTY_WIDTH,
+    PROPERTY_HEIGHT
 
   CSSValueType* = enum
     VALUE_NONE, VALUE_LENGTH, VALUE_COLOR, VALUE_CONTENT, VALUE_DISPLAY,