From 9ab2e5572d3692c7d6b3c67801d9659ba3e5a296 Mon Sep 17 00:00:00 2001 From: "Adam D. Ruppe" Date: Thu, 25 Aug 2022 10:01:31 -0400 Subject: [PATCH] classlist update to JS --- dom.d | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 12 deletions(-) diff --git a/dom.d b/dom.d index 37182cc..0dc9b6c 100644 --- a/dom.d +++ b/dom.d @@ -1,4 +1,3 @@ -// FIXME: add classList. it is a live list and removes whitespace and duplicates when you use it. // FIXME: xml namespace support??? // FIXME: https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML // FIXME: parentElement is parentNode that skips DocumentFragment etc but will be hard to work in with my compatibility... @@ -1556,10 +1555,72 @@ class Element : DomParent { /// get all the classes on this element - @property string[] classes() { - return split(className, " "); + @property string[] classes() const { + // FIXME: remove blank names + auto cs = split(className, " "); + foreach(ref c; cs) + c = c.strip(); + return cs; } + /++ + The object [classList] returns. + +/ + static struct ClassListHelper { + Element this_; + this(inout(Element) this_) inout { + this.this_ = this_; + } + + /// + bool contains(string cn) const { + return this_.hasClass(cn); + } + + /// + void add(string cn) { + this_.addClass(cn); + } + + /// + void remove(string cn) { + this_.removeClass(cn); + } + + /// + void toggle(string cn) { + if(contains(cn)) + remove(cn); + else + add(cn); + } + } + + /++ + Returns a helper object to work with classes, just like javascript. + + History: + Added August 25, 2022 + +/ + @property inout(ClassListHelper) classList() inout { + return inout(ClassListHelper)(this); + } + // FIXME: classList is supposed to whitespace and duplicates when you use it. need to test. + + unittest { + Element element = Element.make("div"); + element.classList.add("foo"); + assert(element.classList.contains("foo")); + element.classList.remove("foo"); + assert(!element.classList.contains("foo")); + element.classList.toggle("bar"); + assert(element.classList.contains("bar")); + } + + /// ditto + alias classNames = classes; + + /// Adds a string to the class attribute. The class attribute is used a lot in CSS. @scriptable Element addClass(string c) { @@ -1597,7 +1658,7 @@ class Element : DomParent { } /// Returns whether the given class appears in this element. - bool hasClass(string c) { + bool hasClass(string c) const { string cn = className; auto idx = cn.indexOf(c); @@ -1605,7 +1666,7 @@ class Element : DomParent { return false; foreach(cla; cn.split(" ")) - if(cla == c) + if(cla.strip == c) return true; return false; @@ -1836,13 +1897,6 @@ class Element : DomParent { return e; } - /** - Splits the className into an array of each class given - */ - string[] classNames() const { - return className().split(" "); - } - /** Fetches the first consecutive text nodes concatenated together.