From b80b11a06d4141c02edc058b248668cfa8c82196 Mon Sep 17 00:00:00 2001 From: btea <2356281422@qq.com> Date: Sun, 5 Jan 2025 18:37:27 +0800 Subject: [PATCH] feat: insert(Before|After) support multiple new node --- API.md | 2 +- postcss-selector-parser.d.ts | 4 ++-- src/__tests__/container.mjs | 20 ++++++++++++++++++++ src/selectors/container.js | 18 +++++++++++++----- 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/API.md b/API.md index c8e55ee..20ad74a 100644 --- a/API.md +++ b/API.md @@ -531,7 +531,7 @@ Arguments: * `node`: The node to add. -### `container.insertBefore(old, new)` & `container.insertAfter(old, new)` +### `container.insertBefore(old, new[, ...newNodes])` & `container.insertAfter(old, new[, ...newNodes])` Add a node before or after an existing node in a container: diff --git a/postcss-selector-parser.d.ts b/postcss-selector-parser.d.ts index eaf1090..2e09127 100644 --- a/postcss-selector-parser.d.ts +++ b/postcss-selector-parser.d.ts @@ -235,8 +235,8 @@ declare namespace parser { removeChild(child: Child): this; removeAll(): this; empty(): this; - insertAfter(oldNode: Child, newNode: Child): this; - insertBefore(oldNode: Child, newNode: Child): this; + insertAfter(oldNode: Child, ...newNode: Child[]): this; + insertBefore(oldNode: Child, ...newNode: Child[]): this; each(callback: (node: Child, index: number) => boolean | void): boolean | undefined; walk( callback: (node: Node, index: number) => boolean | void diff --git a/src/__tests__/container.mjs b/src/__tests__/container.mjs index e852aac..e435ed7 100644 --- a/src/__tests__/container.mjs +++ b/src/__tests__/container.mjs @@ -349,6 +349,16 @@ test('container#insertBefore', (t) => { t.deepEqual(out, 'h1,h2'); }); +test('container#insertBefore (multiple node)', (t) => { + let out = parse('h2', (selectors) => { + let selector = selectors.first; + let clone1 = selector.first.clone({value: 'h1'}); + let clone2 = selector.first.clone({value: 'h0'}); + selectors.insertBefore(selector, clone1, clone2); + }); + t.deepEqual(out, 'h1,h0,h2'); +}); + test('container#insertBefore and node#remove', (t) => { let out = parse('h2', (selectors) => { let selector = selectors.first; @@ -368,6 +378,16 @@ test('container#insertAfter', (t) => { t.deepEqual(out, 'h1,h2'); }); +test('container#insertAfter (multiple node)', (t) => { + let out = parse('h1', (selectors) => { + let selector = selectors.first; + let clone1 = selector.first.clone({value: 'h2'}); + let clone2 = selector.first.clone({value: 'h3'}); + selectors.insertAfter(selector, clone1, clone2); + }); + t.deepEqual(out, 'h1,h2,h3'); +}) + test('container#insertAfter and node#remove', (t) => { let out = parse('h2', (selectors) => { let selector = selectors.first; diff --git a/src/selectors/container.js b/src/selectors/container.js index 2575dde..ee347b4 100644 --- a/src/selectors/container.js +++ b/src/selectors/container.js @@ -78,7 +78,11 @@ export default class Container extends Node { insertAfter (oldNode, newNode) { newNode.parent = this; let oldIndex = this.index(oldNode); - this.nodes.splice(oldIndex + 1, 0, newNode); + const resetNode = []; + for (let i = 2; i < arguments.length; i++) { + resetNode.push(arguments[i]); + } + this.nodes.splice(oldIndex + 1, 0, newNode, ...resetNode); newNode.parent = this; @@ -86,7 +90,7 @@ export default class Container extends Node { for ( let id in this.indexes ) { index = this.indexes[id]; if ( oldIndex < index ) { - this.indexes[id] = index + 1; + this.indexes[id] = index + arguments.length - 1; } } @@ -96,7 +100,11 @@ export default class Container extends Node { insertBefore (oldNode, newNode) { newNode.parent = this; let oldIndex = this.index(oldNode); - this.nodes.splice(oldIndex, 0, newNode); + const resetNode = []; + for (let i = 2; i < arguments.length; i++) { + resetNode.push(arguments[i]); + } + this.nodes.splice(oldIndex, 0, newNode, ...resetNode); newNode.parent = this; @@ -104,7 +112,7 @@ export default class Container extends Node { for ( let id in this.indexes ) { index = this.indexes[id]; if ( index >= oldIndex ) { - this.indexes[id] = index + 1; + this.indexes[id] = index + arguments.length - 1; } } @@ -132,7 +140,7 @@ export default class Container extends Node { * Return the most specific node at the line and column number given. * The source location is based on the original parsed location, locations aren't * updated as selector nodes are mutated. - * + * * Note that this location is relative to the location of the first character * of the selector, and not the location of the selector in the overall document * when used in conjunction with postcss.