diff --git a/index.js b/index.js index 1dd37fa..fae4424 100644 --- a/index.js +++ b/index.js @@ -1,25 +1,79 @@ -const CONDITIONAL_COMMENT_REGEX = /((?:"); - - comments.push({ - isComment: open.startsWith(""); + + stack.push({ + open: openText, + start: openStart, + end: openEnd, + isComment, + bubble, + }); + + position = openEnd; + continue; + } + + // Process closing token + const closeText = closeMatch[0]; + const closeStart = closeMatch.index; + const closeEnd = CLOSE_REGEX.lastIndex; + + if (stack.length > 0) { + const openState = stack[stack.length - 1]; + const closeHasDashes = Boolean(closeMatch[1]); + const openRequiresDashes = openState.isComment; // HTML comment style requires '-->' + + if (closeHasDashes === openRequiresDashes) { + // Valid matching close for the most recent open + stack.pop(); + comments.push({ + isComment: openState.isComment, + open: openState.open, + close: closeText, + bubble: openState.bubble, + downlevel: + openState.bubble || !openState.isComment ? "revealed" : "hidden", + range: [openState.start, closeEnd], + }); + } + } + + position = closeEnd; } return comments; diff --git a/index.test.js b/index.test.js index 17621c7..ced1318 100644 --- a/index.test.js +++ b/index.test.js @@ -68,3 +68,54 @@ test("correctly marks comments as downlevel-revealed or downlevel-hidden", () => `)[0].downlevel ).toEqual("revealed"); }); + +test("supports nested conditional comments", () => { + const html = ` + + Outer end + + `; + + const result = findConditionalComments(html); + + expect(result.length).toBe(2); + + // Identify outer and inner by range size + const sorted = [...result].sort( + (a, b) => a.range[1] - a.range[0] - (b.range[1] - b.range[0]) + ); + const inner = sorted[0]; + const outer = sorted[1]; + + expect(inner.open.startsWith("/); + expect(inner.isComment).toBe(true); + expect(inner.downlevel).toBe("hidden"); + + expect(outer.open.startsWith("/); + expect(outer.isComment).toBe(true); + expect(outer.downlevel).toBe("hidden"); + + // Inner range should be fully inside outer range + expect(inner.range[0]).toBeGreaterThan(outer.range[0]); + expect(inner.range[1]).toBeLessThan(outer.range[1]); +}); + +test("rejects mismatched closing dashes for HTML-comment style open", () => { + const html = ` + + `; + const result = findConditionalComments(html); + expect(result.length).toBe(0); +}); diff --git a/package-lock.json b/package-lock.json index 6d46078..314e3b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "find-conditional-comments", - "version": "0.0.4", + "version": "0.0.6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "find-conditional-comments", - "version": "0.0.4", + "version": "0.0.6", "license": "MIT", "devDependencies": { "husky": "^4.3.0",