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/select.nim45
-rw-r--r--src/html/dom.nim17
2 files changed, 62 insertions, 0 deletions
diff --git a/src/css/select.nim b/src/css/select.nim
index 10f87113..1fa01ac5 100644
--- a/src/css/select.nim
+++ b/src/css/select.nim
@@ -140,6 +140,37 @@ func selectElems(document: Document, selectors: SelectorList): seq[Element] =
     result = result.filter((elem) => selectorMatches(elem, sellist[i]))
     inc i
 
+func selectElems(element: Element, sel: Selector): seq[Element] =
+  case sel.t
+  of TYPE_SELECTOR:
+    return element.filterDescendants((elem) => elem.tagType == sel.tag)
+  of ID_SELECTOR:
+    return element.filterDescendants((elem) => elem.id == sel.id)
+  of CLASS_SELECTOR:
+    return element.filterDescendants((elem) => sel.class in elem.classList)
+  of UNIVERSAL_SELECTOR:
+    return element.all_descendants
+  of ATTR_SELECTOR:
+    return element.filterDescendants((elem) => attrSelectorMatches(elem, sel))
+  of PSEUDO_SELECTOR:
+    return element.filterDescendants((elem) => pseudoSelectorMatches(elem, sel))
+  of PSELEM_SELECTOR:
+    return element.all_descendants
+  of FUNC_SELECTOR:
+    return element.filterDescendants((elem) => selectorMatches(elem, sel))
+  of COMBINATOR_SELECTOR:
+    return element.filterDescendants((elem) => selectorMatches(elem, sel))
+
+func selectElems(element: Element, selectors: SelectorList): seq[Element] =
+  assert(selectors.len > 0)
+  let sellist = optimizeSelectorList(selectors)
+  result = element.selectElems(selectors[0])
+  var i = 1
+
+  while i < sellist.len:
+    result = result.filter((elem) => selectorMatches(elem, sellist[i]))
+    inc i
+
 proc querySelectorAll*(document: Document, q: string): seq[Element] =
   let ss = newStringStream(q)
   let cvals = parseListOfComponentValues(ss)
@@ -153,3 +184,17 @@ proc querySelector*(document: Document, q: string): Element =
   if elems.len > 0:
     return elems[0]
   return nil
+
+proc querySelectorAll*(element: Element, q: string): seq[Element] =
+  let ss = newStringStream(q)
+  let cvals = parseListOfComponentValues(ss)
+  let selectors = parseSelectors(cvals)
+
+  for sel in selectors:
+    result.add(element.selectElems(sel))
+
+proc querySelector*(element: Element, q: string): Element =
+  let elems = element.querySelectorAll(q)
+  if elems.len > 0:
+    return elems[0]
+  return nil
diff --git a/src/html/dom.nim b/src/html/dom.nim
index d50c1c8e..aaa33163 100644
--- a/src/html/dom.nim
+++ b/src/html/dom.nim
@@ -199,6 +199,23 @@ iterator branch*(node: Node): Node {.inline.} =
     yield node
     node = node.parentElement
 
+func filterDescendants*(element: Element, predicate: (proc(child: Element): bool)): seq[Element] =
+  var stack: seq[Element]
+  stack.add(element.children)
+  while stack.len > 0:
+    let child = stack.pop()
+    if predicate(child):
+      result.add(child)
+    stack.add(child.children)
+
+func all_descendants*(element: Element): seq[Element] =
+  var stack: seq[Element]
+  stack.add(element.children)
+  while stack.len > 0:
+    let child = stack.pop()
+    result.add(child)
+    stack.add(child.children)
+
 # a == b or b in a's ancestors
 func contains*(a, b: Node): bool =
   for node in a.branch: