From 1221b88d9f64ea2cd1a2e7d91f167ace8e29e096 Mon Sep 17 00:00:00 2001 From: Simon Lecoq <22963968+lowlighter@users.noreply.github.com> Date: Sun, 21 Apr 2024 17:07:31 +0000 Subject: [PATCH 1/3] feat: implement Element.toggleAttribute --- src/dom/element.ts | 12 ++++++++++ test/units/Element-toggleAttribute.ts | 32 +++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 test/units/Element-toggleAttribute.ts diff --git a/src/dom/element.ts b/src/dom/element.ts index 1edf082..0c928fd 100644 --- a/src/dom/element.ts +++ b/src/dom/element.ts @@ -801,6 +801,18 @@ export class Element extends Node { } } + toggleAttribute(rawName: string, force?: boolean) { + const name = String(rawName?.toLowerCase()); + if (force === undefined) { + force = !this.hasAttribute(name); + } + if (force) { + this.setAttribute(name, ""); + } else { + this.removeAttribute(name); + } + } + hasAttribute(name: string): boolean { return this.attributes[getNamedNodeMapValueSym]( String(name?.toLowerCase()), diff --git a/test/units/Element-toggleAttribute.ts b/test/units/Element-toggleAttribute.ts new file mode 100644 index 0000000..4d082db --- /dev/null +++ b/test/units/Element-toggleAttribute.ts @@ -0,0 +1,32 @@ +import { DOMParser } from "../../deno-dom-wasm.ts"; +import { + assert, + assertEquals, +} from "https://deno.land/std@0.85.0/testing/asserts.ts"; + +Deno.test("Element.toggleAttribute toggles attribute", () => { + const doc = new DOMParser().parseFromString( + ``, + "text/html", + )!; + + const input = doc.querySelector("input")!; + assert(!input.hasAttribute("disabled")); + + for (const _ of [1, 2]) { + input.toggleAttribute("disabled", true); + assertEquals(input.outerHTML, ``); + } + + for (const _ of [1, 2]) { + input.toggleAttribute("disabled", false); + assertEquals(input.outerHTML, ``); + } + + for (const _ of [1, 2]) { + input.toggleAttribute("disabled"); + assertEquals(input.outerHTML, ``); + input.toggleAttribute("disabled"); + assertEquals(input.outerHTML, ``); + } +}); From 5f13e00e434586102c378dde0d2296e651f3c3e3 Mon Sep 17 00:00:00 2001 From: Simon Lecoq <22963968+lowlighter@users.noreply.github.com> Date: Wed, 1 May 2024 22:04:45 +0000 Subject: [PATCH 2/3] fix: compliancy with spec --- src/dom/element.ts | 20 +++++++++++++------- test/units/Element-toggleAttribute.ts | 20 ++++++++++++++++---- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/dom/element.ts b/src/dom/element.ts index 0c928fd..6e249d1 100644 --- a/src/dom/element.ts +++ b/src/dom/element.ts @@ -803,13 +803,19 @@ export class Element extends Node { toggleAttribute(rawName: string, force?: boolean) { const name = String(rawName?.toLowerCase()); - if (force === undefined) { - force = !this.hasAttribute(name); - } - if (force) { - this.setAttribute(name, ""); - } else { - this.removeAttribute(name); + switch (this.hasAttribute(name)) { + case true: + if ((force === undefined) || (force === false)) { + this.removeAttribute(name); + return false; + } + return true; + case false: + if ((force === undefined) || (force === true)) { + this.setAttribute(name, ""); + return true; + } + return false; } } diff --git a/test/units/Element-toggleAttribute.ts b/test/units/Element-toggleAttribute.ts index 4d082db..1faf5d4 100644 --- a/test/units/Element-toggleAttribute.ts +++ b/test/units/Element-toggleAttribute.ts @@ -14,19 +14,31 @@ Deno.test("Element.toggleAttribute toggles attribute", () => { assert(!input.hasAttribute("disabled")); for (const _ of [1, 2]) { - input.toggleAttribute("disabled", true); + assertEquals(input.toggleAttribute("disabled", true), true); assertEquals(input.outerHTML, ``); } for (const _ of [1, 2]) { - input.toggleAttribute("disabled", false); + assertEquals(input.toggleAttribute("disabled", false), false); assertEquals(input.outerHTML, ``); } for (const _ of [1, 2]) { - input.toggleAttribute("disabled"); + input.toggleAttribute("disabled", true); assertEquals(input.outerHTML, ``); - input.toggleAttribute("disabled"); + input.toggleAttribute("disabled", false); assertEquals(input.outerHTML, ``); } }); + +Deno.test("Element.toggleAttribute does not override value when forced", () => { + const doc = new DOMParser().parseFromString( + ``, + "text/html", + )!; + + const input = doc.querySelector("input")!; + input.toggleAttribute("disabled", true); + assert(input.hasAttribute("disabled")); + assertEquals(input.outerHTML, ``); +}); From 2f774ce6018185d212976adf1ac667eb9e40a00e Mon Sep 17 00:00:00 2001 From: Simon Lecoq <22963968+lowlighter@users.noreply.github.com> Date: Sat, 4 May 2024 00:40:07 +0000 Subject: [PATCH 3/3] fix: recommandations --- src/dom/element.ts | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/dom/element.ts b/src/dom/element.ts index 6e249d1..d0446e7 100644 --- a/src/dom/element.ts +++ b/src/dom/element.ts @@ -803,20 +803,18 @@ export class Element extends Node { toggleAttribute(rawName: string, force?: boolean) { const name = String(rawName?.toLowerCase()); - switch (this.hasAttribute(name)) { - case true: - if ((force === undefined) || (force === false)) { - this.removeAttribute(name); - return false; - } - return true; - case false: - if ((force === undefined) || (force === true)) { - this.setAttribute(name, ""); - return true; - } + if (this.hasAttribute(name)) { + if ((force === undefined) || (force === false)) { + this.removeAttribute(name); return false; + } + return true; + } + if ((force === undefined) || (force === true)) { + this.setAttribute(name, ""); + return true; } + return false; } hasAttribute(name: string): boolean {