feat: make `preserveComments` effective in DOM renderer (#7182)

pull/8425/head
esthe 2 years ago committed by GitHub
parent 91e8dfcd6d
commit 95c46552fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,41 @@
import Renderer from '../Renderer';
import Block from '../Block';
import Comment from '../../nodes/Comment';
import Wrapper from './shared/Wrapper';
import { x } from 'code-red';
import { Identifier } from 'estree';
export default class CommentWrapper extends Wrapper {
node: Comment;
var: Identifier;
constructor(
renderer: Renderer,
block: Block,
parent: Wrapper,
node: Comment
) {
super(renderer, block, parent, node);
this.var = x`c` as Identifier;
}
render(block: Block, parent_node: Identifier, parent_nodes: Identifier) {
if (!this.renderer.options.preserveComments) return;
const string_literal = {
type: 'Literal',
value: this.node.data,
loc: {
start: this.renderer.locate(this.node.start),
end: this.renderer.locate(this.node.end)
}
};
block.add_element(
this.var,
x`@comment(${string_literal})`,
parent_nodes && x`@claim_comment(${parent_nodes}, ${string_literal})`,
parent_node
);
}
}

@ -14,6 +14,7 @@ import RawMustacheTag from './RawMustacheTag';
import Slot from './Slot'; import Slot from './Slot';
import SlotTemplate from './SlotTemplate'; import SlotTemplate from './SlotTemplate';
import Text from './Text'; import Text from './Text';
import Comment from './Comment';
import Title from './Title'; import Title from './Title';
import Window from './Window'; import Window from './Window';
import { INode } from '../../nodes/interfaces'; import { INode } from '../../nodes/interfaces';
@ -27,7 +28,7 @@ import { regex_starts_with_whitespace } from '../../../utils/patterns';
const wrappers = { const wrappers = {
AwaitBlock, AwaitBlock,
Body, Body,
Comment: null, Comment,
DebugTag, DebugTag,
Document, Document,
EachBlock, EachBlock,
@ -118,7 +119,7 @@ export default class FragmentWrapper {
link(last_child, last_child = wrapper); link(last_child, last_child = wrapper);
} else { } else {
const Wrapper = wrappers[child.type]; const Wrapper = wrappers[child.type];
if (!Wrapper) continue; if (!Wrapper || (child.type === 'Comment' && !renderer.options.preserveComments)) continue;
const wrapper = new Wrapper(renderer, block, parent, child, strip_whitespace, last_child || next_sibling); const wrapper = new Wrapper(renderer, block, parent, child, strip_whitespace, last_child || next_sibling);
this.nodes.unshift(wrapper); this.nodes.unshift(wrapper);

@ -254,6 +254,10 @@ export function empty() {
return text(''); return text('');
} }
export function comment(content: string) {
return document.createComment(content);
}
export function listen(node: EventTarget, event: string, handler: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | EventListenerOptions) { export function listen(node: EventTarget, event: string, handler: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | EventListenerOptions) {
node.addEventListener(event, handler, options); node.addEventListener(event, handler, options);
return () => node.removeEventListener(event, handler, options); return () => node.removeEventListener(event, handler, options);
@ -550,6 +554,19 @@ export function claim_space(nodes) {
return claim_text(nodes, ' '); return claim_text(nodes, ' ');
} }
export function claim_comment(nodes:ChildNodeArray, data) {
return claim_node<Comment>(
nodes,
(node: ChildNode): node is Comment => node.nodeType === 8,
(node: Comment) => {
node.data = '' + data;
return undefined;
},
() => comment(data),
true
);
}
function find_comment(nodes, text, start) { function find_comment(nodes, text, start) {
for (let i = start; i < nodes.length; i += 1) { for (let i = start; i < nodes.length; i += 1) {
const node = nodes[i]; const node = nodes[i];

@ -0,0 +1 @@
<div><!-- test1 --><!-- test2 --></div>

@ -0,0 +1,20 @@
export default {
compileOptions: {
preserveComments:true
},
snapshot(target) {
const div = target.querySelector('div');
return {
div,
comment: div.childNodes[0]
};
},
test(assert, target, snapshot) {
const div = target.querySelector('div');
assert.equal(div, snapshot.div);
assert.equal(div.childNodes[0], snapshot.comment);
assert.equal(div.childNodes[1].nodeType, 8);
}
};

@ -0,0 +1 @@
<div><!-- test1 --><!-- test2 --></div>

@ -0,0 +1,5 @@
export default {
options: {
preserveComments: true
}
};

@ -0,0 +1,58 @@
/* generated by Svelte vX.Y.Z */
import {
SvelteComponent,
comment,
detach,
element,
init,
insert,
noop,
safe_not_equal,
space
} from "svelte/internal";
function create_fragment(ctx) {
let div0;
let t1;
let c;
let t2;
let div1;
return {
c() {
div0 = element("div");
div0.textContent = "content";
t1 = space();
c = comment(" comment ");
t2 = space();
div1 = element("div");
div1.textContent = "more content";
},
m(target, anchor) {
insert(target, div0, anchor);
insert(target, t1, anchor);
insert(target, c, anchor);
insert(target, t2, anchor);
insert(target, div1, anchor);
},
p: noop,
i: noop,
o: noop,
d(detaching) {
if (detaching) detach(div0);
if (detaching) detach(t1);
if (detaching) detach(c);
if (detaching) detach(t2);
if (detaching) detach(div1);
}
};
}
class Component extends SvelteComponent {
constructor(options) {
super();
init(this, options, null, create_fragment, safe_not_equal, {});
}
}
export default Component;

@ -0,0 +1,3 @@
<div>content</div>
<!-- comment -->
<div>more content</div>
Loading…
Cancel
Save