|
|
|
@ -19,6 +19,10 @@ const LINE_BREAK_THRESHOLD = 50;
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export function print(ast, options = undefined) {
|
|
|
|
export function print(ast, options = undefined) {
|
|
|
|
const comments = (ast.type === 'Root' && ast.comments) || [];
|
|
|
|
const comments = (ast.type === 'Root' && ast.comments) || [];
|
|
|
|
|
|
|
|
const state = { preserve_whitespace: 0 };
|
|
|
|
|
|
|
|
const css_comments =
|
|
|
|
|
|
|
|
(ast.type === 'Root' ? ast.css?.comments : ast.type === 'StyleSheet' ? ast.comments : null) ||
|
|
|
|
|
|
|
|
[];
|
|
|
|
|
|
|
|
|
|
|
|
return esrap.print(
|
|
|
|
return esrap.print(
|
|
|
|
ast,
|
|
|
|
ast,
|
|
|
|
@ -28,8 +32,8 @@ export function print(ast, options = undefined) {
|
|
|
|
getLeadingComments: options?.getLeadingComments,
|
|
|
|
getLeadingComments: options?.getLeadingComments,
|
|
|
|
getTrailingComments: options?.getTrailingComments
|
|
|
|
getTrailingComments: options?.getTrailingComments
|
|
|
|
}),
|
|
|
|
}),
|
|
|
|
...svelte_visitors(comments),
|
|
|
|
...svelte_visitors(comments, state),
|
|
|
|
...css_visitors
|
|
|
|
...css_visitors(css_comments, comments)
|
|
|
|
}),
|
|
|
|
}),
|
|
|
|
{
|
|
|
|
{
|
|
|
|
indent: options?.indent
|
|
|
|
indent: options?.indent
|
|
|
|
@ -40,9 +44,15 @@ export function print(ast, options = undefined) {
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @param {Context} context
|
|
|
|
* @param {Context} context
|
|
|
|
* @param {AST.SvelteNode} node
|
|
|
|
* @param {AST.SvelteNode} node
|
|
|
|
|
|
|
|
* @param {boolean} preserve_whitespace
|
|
|
|
* @param {boolean} allow_inline
|
|
|
|
* @param {boolean} allow_inline
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
function block(context, node, allow_inline = false) {
|
|
|
|
function block(context, node, preserve_whitespace = false, allow_inline = false) {
|
|
|
|
|
|
|
|
if (preserve_whitespace) {
|
|
|
|
|
|
|
|
context.visit(node);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const child_context = context.new();
|
|
|
|
const child_context = context.new();
|
|
|
|
child_context.visit(node);
|
|
|
|
child_context.visit(node);
|
|
|
|
|
|
|
|
|
|
|
|
@ -82,6 +92,7 @@ function attributes(node, attributes, context, comments) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const separator = context.new();
|
|
|
|
const separator = context.new();
|
|
|
|
|
|
|
|
let previous_attribute_end = node.start;
|
|
|
|
|
|
|
|
|
|
|
|
const children = attributes.map((attribute) => {
|
|
|
|
const children = attributes.map((attribute) => {
|
|
|
|
const child_context = context.new();
|
|
|
|
const child_context = context.new();
|
|
|
|
@ -90,12 +101,16 @@ function attributes(node, attributes, context, comments) {
|
|
|
|
const comment = comments[comment_index];
|
|
|
|
const comment = comments[comment_index];
|
|
|
|
|
|
|
|
|
|
|
|
if (comment.start < attribute.start) {
|
|
|
|
if (comment.start < attribute.start) {
|
|
|
|
if (comment.type === 'Line') {
|
|
|
|
// Inside a previous attribute's value can be comments which don't
|
|
|
|
child_context.write('//' + comment.value);
|
|
|
|
// advance comment_index, therefore this additional check
|
|
|
|
child_context.newline();
|
|
|
|
if (comment.start >= previous_attribute_end) {
|
|
|
|
} else {
|
|
|
|
if (comment.type === 'Line') {
|
|
|
|
child_context.write('/*' + comment.value + '*/'); // TODO match indentation?
|
|
|
|
child_context.write('//' + comment.value);
|
|
|
|
child_context.append(separator);
|
|
|
|
child_context.newline();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
child_context.write('/*' + comment.value + '*/'); // TODO match indentation?
|
|
|
|
|
|
|
|
child_context.append(separator);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
comment_index += 1;
|
|
|
|
comment_index += 1;
|
|
|
|
@ -105,6 +120,7 @@ function attributes(node, attributes, context, comments) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
child_context.visit(attribute);
|
|
|
|
child_context.visit(attribute);
|
|
|
|
|
|
|
|
previous_attribute_end = attribute.end;
|
|
|
|
|
|
|
|
|
|
|
|
length += child_context.measure() + 1;
|
|
|
|
length += child_context.measure() + 1;
|
|
|
|
|
|
|
|
|
|
|
|
@ -137,8 +153,9 @@ function attributes(node, attributes, context, comments) {
|
|
|
|
* @param {AST.BaseElement} node
|
|
|
|
* @param {AST.BaseElement} node
|
|
|
|
* @param {Context} context
|
|
|
|
* @param {Context} context
|
|
|
|
* @param {AST.JSComment[]} comments
|
|
|
|
* @param {AST.JSComment[]} comments
|
|
|
|
|
|
|
|
* @param {{ preserve_whitespace: number }} state
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
function base_element(node, context, comments) {
|
|
|
|
function base_element(node, context, comments, state) {
|
|
|
|
const child_context = context.new();
|
|
|
|
const child_context = context.new();
|
|
|
|
|
|
|
|
|
|
|
|
child_context.write('<' + node.name);
|
|
|
|
child_context.write('<' + node.name);
|
|
|
|
@ -164,174 +181,294 @@ function base_element(node, context, comments) {
|
|
|
|
child_context.write(`${multiline_attributes ? '' : ' '}/>`);
|
|
|
|
child_context.write(`${multiline_attributes ? '' : ' '}/>`);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
child_context.write('>');
|
|
|
|
child_context.write('>');
|
|
|
|
block(child_context, node.fragment, true);
|
|
|
|
block(child_context, node.fragment, state.preserve_whitespace > 0, true);
|
|
|
|
child_context.write(`</${node.name}>`);
|
|
|
|
child_context.write(`</${node.name}>`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
context.append(child_context);
|
|
|
|
context.append(child_context);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** @type {Visitors<AST.SvelteNode>} */
|
|
|
|
/**
|
|
|
|
const css_visitors = {
|
|
|
|
* @param {AST.BaseElement} node
|
|
|
|
Atrule(node, context) {
|
|
|
|
* @param {Context} context
|
|
|
|
context.write(`@${node.name}`);
|
|
|
|
* @param {AST.JSComment[]} comments
|
|
|
|
if (node.prelude) context.write(` ${node.prelude}`);
|
|
|
|
* @param {{ preserve_whitespace: number }} state
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
function print_element(node, context, comments, state) {
|
|
|
|
|
|
|
|
const name = node.name.toLowerCase();
|
|
|
|
|
|
|
|
const preserve =
|
|
|
|
|
|
|
|
(node.type === 'RegularElement' || node.type === 'TitleElement') &&
|
|
|
|
|
|
|
|
(name === 'pre' || name === 'textarea' || name === 'title');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (preserve) state.preserve_whitespace += 1;
|
|
|
|
|
|
|
|
base_element(node, context, comments, state);
|
|
|
|
|
|
|
|
if (preserve) state.preserve_whitespace -= 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (node.block) {
|
|
|
|
/**
|
|
|
|
context.write(' ');
|
|
|
|
* @param {AST.CSS.CSSComment[]} comments
|
|
|
|
context.visit(node.block);
|
|
|
|
* @param {AST.JSComment[]} js_comments
|
|
|
|
} else {
|
|
|
|
* @returns {Visitors<AST.SvelteNode>}
|
|
|
|
context.write(';');
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
function css_visitors(comments, js_comments) {
|
|
|
|
},
|
|
|
|
let comment_index = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** @param {number} end */
|
|
|
|
|
|
|
|
const has_comment_before = (end) => comments[comment_index]?.start < end;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @param {Context} context
|
|
|
|
|
|
|
|
* @param {AST.CSS.CSSComment} comment
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
function write_comment(context, comment) {
|
|
|
|
|
|
|
|
context.write(`/*${comment.value}*/`);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AttributeSelector(node, context) {
|
|
|
|
/**
|
|
|
|
context.write(`[${node.name}`);
|
|
|
|
* @param {Context} context
|
|
|
|
if (node.matcher) {
|
|
|
|
* @param {number} end
|
|
|
|
context.write(node.matcher);
|
|
|
|
*/
|
|
|
|
context.write(`"${node.value}"`);
|
|
|
|
function write_inline_comments(context, end) {
|
|
|
|
if (node.flags) {
|
|
|
|
let written = false;
|
|
|
|
context.write(` ${node.flags}`);
|
|
|
|
|
|
|
|
}
|
|
|
|
while (has_comment_before(end)) {
|
|
|
|
|
|
|
|
if (written) context.write(' ');
|
|
|
|
|
|
|
|
write_comment(context, comments[comment_index++]);
|
|
|
|
|
|
|
|
written = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
context.write(']');
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Block(node, context) {
|
|
|
|
return written;
|
|
|
|
context.write('{');
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (node.children.length > 0) {
|
|
|
|
/**
|
|
|
|
context.indent();
|
|
|
|
* @param {Context} context
|
|
|
|
context.newline();
|
|
|
|
* @param {string} value
|
|
|
|
|
|
|
|
* @param {number} end
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
function write_value(context, value, end) {
|
|
|
|
|
|
|
|
let offset = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (has_comment_before(end)) {
|
|
|
|
|
|
|
|
const comment = comments[comment_index++];
|
|
|
|
|
|
|
|
const position = Math.max(offset, Math.min(comment.position ?? 0, value.length));
|
|
|
|
|
|
|
|
context.write(value.slice(offset, position));
|
|
|
|
|
|
|
|
write_comment(context, comment);
|
|
|
|
|
|
|
|
offset = position;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let started = false;
|
|
|
|
context.write(value.slice(offset));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (const child of node.children) {
|
|
|
|
/**
|
|
|
|
if (started) {
|
|
|
|
* @param {Context} context
|
|
|
|
context.newline();
|
|
|
|
* @param {Array<AST.CSS.Rule | AST.CSS.Atrule | AST.CSS.Declaration>} children
|
|
|
|
}
|
|
|
|
* @param {number} end
|
|
|
|
|
|
|
|
* @param {boolean} margins
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
function print_children(context, children, end, margins) {
|
|
|
|
|
|
|
|
let started = false;
|
|
|
|
|
|
|
|
|
|
|
|
context.visit(child);
|
|
|
|
const separate = () => {
|
|
|
|
|
|
|
|
if (!started) return;
|
|
|
|
|
|
|
|
if (margins) context.margin();
|
|
|
|
|
|
|
|
context.newline();
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const child of children) {
|
|
|
|
|
|
|
|
while (has_comment_before(child.start)) {
|
|
|
|
|
|
|
|
separate();
|
|
|
|
|
|
|
|
write_comment(context, comments[comment_index++]);
|
|
|
|
started = true;
|
|
|
|
started = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
context.dedent();
|
|
|
|
separate();
|
|
|
|
context.newline();
|
|
|
|
context.visit(child);
|
|
|
|
|
|
|
|
started = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
context.write('}');
|
|
|
|
while (has_comment_before(end)) {
|
|
|
|
},
|
|
|
|
separate();
|
|
|
|
|
|
|
|
write_comment(context, comments[comment_index++]);
|
|
|
|
|
|
|
|
started = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ClassSelector(node, context) {
|
|
|
|
/**
|
|
|
|
context.write(`.${node.name}`);
|
|
|
|
* @param {AST.CSS.SelectorList} node
|
|
|
|
},
|
|
|
|
* @param {Context} context
|
|
|
|
|
|
|
|
* @param {boolean} multiline
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
function print_selector_list(node, context, multiline) {
|
|
|
|
|
|
|
|
let needs_separator = false;
|
|
|
|
|
|
|
|
let remaining_selectors = node.children.length;
|
|
|
|
|
|
|
|
|
|
|
|
ComplexSelector(node, context) {
|
|
|
|
|
|
|
|
for (const selector of node.children) {
|
|
|
|
for (const selector of node.children) {
|
|
|
|
|
|
|
|
while (has_comment_before(selector.start)) {
|
|
|
|
|
|
|
|
if (needs_separator) context.write(' ');
|
|
|
|
|
|
|
|
write_comment(context, comments[comment_index++]);
|
|
|
|
|
|
|
|
needs_separator = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (needs_separator) {
|
|
|
|
|
|
|
|
if (multiline) context.newline();
|
|
|
|
|
|
|
|
else context.write(' ');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
context.visit(selector);
|
|
|
|
context.visit(selector);
|
|
|
|
|
|
|
|
needs_separator = true;
|
|
|
|
|
|
|
|
remaining_selectors -= 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (remaining_selectors > 0) context.write(',');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Declaration(node, context) {
|
|
|
|
return {
|
|
|
|
context.write(`${node.property}: ${node.value};`);
|
|
|
|
Atrule(node, context) {
|
|
|
|
},
|
|
|
|
context.write(`@${node.name}`);
|
|
|
|
|
|
|
|
|
|
|
|
IdSelector(node, context) {
|
|
|
|
const prelude_end = node.block?.start ?? node.end;
|
|
|
|
context.write(`#${node.name}`);
|
|
|
|
if (node.prelude || has_comment_before(prelude_end)) {
|
|
|
|
},
|
|
|
|
context.write(' ');
|
|
|
|
|
|
|
|
write_value(context, node.prelude, prelude_end);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NestingSelector(node, context) {
|
|
|
|
if (node.block) {
|
|
|
|
context.write('&');
|
|
|
|
context.write(' ');
|
|
|
|
},
|
|
|
|
context.visit(node.block);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
context.write(';');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AttributeSelector(node, context) {
|
|
|
|
|
|
|
|
context.write(`[${node.name}`);
|
|
|
|
|
|
|
|
if (node.matcher) {
|
|
|
|
|
|
|
|
context.write(node.matcher);
|
|
|
|
|
|
|
|
context.write(`"${node.value}"`);
|
|
|
|
|
|
|
|
if (node.flags) context.write(` ${node.flags}`);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
context.write(']');
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
Nth(node, context) {
|
|
|
|
Block(node, context) {
|
|
|
|
context.write(node.value);
|
|
|
|
context.write('{');
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Percentage(node, context) {
|
|
|
|
if (node.children.length > 0 || has_comment_before(node.end)) {
|
|
|
|
context.write(node.value);
|
|
|
|
context.indent();
|
|
|
|
},
|
|
|
|
context.newline();
|
|
|
|
|
|
|
|
print_children(context, node.children, node.end, false);
|
|
|
|
|
|
|
|
context.dedent();
|
|
|
|
|
|
|
|
context.newline();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PseudoClassSelector(node, context) {
|
|
|
|
context.write('}');
|
|
|
|
context.write(`:${node.name}`);
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
if (node.args) {
|
|
|
|
ClassSelector(node, context) {
|
|
|
|
context.write('(');
|
|
|
|
context.write(`.${node.name}`);
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
let started = false;
|
|
|
|
ComplexSelector(node, context) {
|
|
|
|
|
|
|
|
for (const selector of node.children) context.visit(selector);
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
for (const arg of node.args.children) {
|
|
|
|
Declaration(node, context) {
|
|
|
|
if (started) {
|
|
|
|
context.write(`${node.property}: `);
|
|
|
|
context.write(', ');
|
|
|
|
write_value(context, node.value, node.end);
|
|
|
|
}
|
|
|
|
context.write(';');
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
context.visit(arg);
|
|
|
|
IdSelector(node, context) {
|
|
|
|
|
|
|
|
context.write(`#${node.name}`);
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
started = true;
|
|
|
|
NestingSelector(node, context) {
|
|
|
|
}
|
|
|
|
context.write('&');
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
context.write(')');
|
|
|
|
Nth(node, context) {
|
|
|
|
}
|
|
|
|
context.write(node.value);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
PseudoElementSelector(node, context) {
|
|
|
|
Percentage(node, context) {
|
|
|
|
context.write(`::${node.name}`);
|
|
|
|
context.write(node.value);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
RelativeSelector(node, context) {
|
|
|
|
PseudoClassSelector(node, context) {
|
|
|
|
if (node.combinator) {
|
|
|
|
context.write(`:${node.name}`);
|
|
|
|
if (node.combinator.name === ' ') {
|
|
|
|
|
|
|
|
context.write(' ');
|
|
|
|
if (node.args) {
|
|
|
|
} else {
|
|
|
|
context.write('(');
|
|
|
|
context.write(` ${node.combinator.name} `);
|
|
|
|
context.visit(node.args);
|
|
|
|
|
|
|
|
if (has_comment_before(node.end)) {
|
|
|
|
|
|
|
|
context.write(' ');
|
|
|
|
|
|
|
|
write_inline_comments(context, node.end);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
context.write(')');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PseudoElementSelector(node, context) {
|
|
|
|
|
|
|
|
context.write(`::${node.name}`);
|
|
|
|
|
|
|
|
if (node.args) {
|
|
|
|
|
|
|
|
context.write('(');
|
|
|
|
|
|
|
|
context.visit(node.args);
|
|
|
|
|
|
|
|
if (has_comment_before(node.end)) {
|
|
|
|
|
|
|
|
context.write(' ');
|
|
|
|
|
|
|
|
write_inline_comments(context, node.end);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
context.write(')');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
for (const selector of node.selectors) {
|
|
|
|
RelativeSelector(node, context) {
|
|
|
|
context.visit(selector);
|
|
|
|
if (node.combinator) {
|
|
|
|
}
|
|
|
|
if (node.combinator.name === ' ') context.write(' ');
|
|
|
|
},
|
|
|
|
else context.write(` ${node.combinator.name} `);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Rule(node, context) {
|
|
|
|
for (const selector of node.selectors) context.visit(selector);
|
|
|
|
let started = false;
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
for (const selector of node.prelude.children) {
|
|
|
|
Rule(node, context) {
|
|
|
|
if (started) {
|
|
|
|
print_selector_list(node.prelude, context, true);
|
|
|
|
context.write(',');
|
|
|
|
context.write(' ');
|
|
|
|
context.newline();
|
|
|
|
if (write_inline_comments(context, node.block.start)) context.write(' ');
|
|
|
|
}
|
|
|
|
context.visit(node.block);
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
context.visit(selector);
|
|
|
|
SelectorList(node, context) {
|
|
|
|
started = true;
|
|
|
|
print_selector_list(node, context, false);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
context.write(' ');
|
|
|
|
StyleSheet(node, context) {
|
|
|
|
context.visit(node.block);
|
|
|
|
context.write('<style');
|
|
|
|
},
|
|
|
|
attributes(node, node.attributes, context, js_comments);
|
|
|
|
|
|
|
|
context.write('>');
|
|
|
|
|
|
|
|
|
|
|
|
SelectorList(node, context) {
|
|
|
|
if (node.children.length > 0 || node.comments.length > 0) {
|
|
|
|
let started = false;
|
|
|
|
context.indent();
|
|
|
|
for (const selector of node.children) {
|
|
|
|
context.newline();
|
|
|
|
if (started) {
|
|
|
|
print_children(context, node.children, node.content.end, true);
|
|
|
|
context.write(', ');
|
|
|
|
context.dedent();
|
|
|
|
|
|
|
|
context.newline();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
context.visit(selector);
|
|
|
|
context.write('</style>');
|
|
|
|
started = true;
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TypeSelector(node, context) {
|
|
|
|
TypeSelector(node, context) {
|
|
|
|
context.write(node.name);
|
|
|
|
context.write(node.name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @param {AST.JSComment[]} comments
|
|
|
|
* @param {AST.JSComment[]} comments
|
|
|
|
|
|
|
|
* @param {{ preserve_whitespace: number }} state
|
|
|
|
* @returns {Visitors<AST.SvelteNode>}
|
|
|
|
* @returns {Visitors<AST.SvelteNode>}
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
const svelte_visitors = (comments) => ({
|
|
|
|
const svelte_visitors = (comments, state) => ({
|
|
|
|
Root(node, context) {
|
|
|
|
Root(node, context) {
|
|
|
|
if (node.options) {
|
|
|
|
if (node.options) {
|
|
|
|
context.write('<svelte:options');
|
|
|
|
context.write('<svelte:options');
|
|
|
|
@ -363,11 +500,27 @@ const svelte_visitors = (comments) => ({
|
|
|
|
context.write('<script');
|
|
|
|
context.write('<script');
|
|
|
|
attributes(node, node.attributes, context, comments);
|
|
|
|
attributes(node, node.attributes, context, comments);
|
|
|
|
context.write('>');
|
|
|
|
context.write('>');
|
|
|
|
block(context, node.content);
|
|
|
|
block(context, node.content, state.preserve_whitespace > 0);
|
|
|
|
context.write('</script>');
|
|
|
|
context.write('</script>');
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
Fragment(node, context) {
|
|
|
|
Fragment(node, context) {
|
|
|
|
|
|
|
|
if (state.preserve_whitespace > 0) {
|
|
|
|
|
|
|
|
for (const child of node.nodes) {
|
|
|
|
|
|
|
|
context.visit(child);
|
|
|
|
|
|
|
|
context.multiline ||= child.type === 'Text' && /[\r\n]/.test(child.data);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const first = node.nodes[0];
|
|
|
|
|
|
|
|
const last = node.nodes.at(-1);
|
|
|
|
|
|
|
|
const has_surrounding_whitespace =
|
|
|
|
|
|
|
|
first?.type === 'Text' &&
|
|
|
|
|
|
|
|
/^\s/.test(first.data) &&
|
|
|
|
|
|
|
|
last?.type === 'Text' &&
|
|
|
|
|
|
|
|
/\s$/.test(last.data);
|
|
|
|
|
|
|
|
|
|
|
|
/** @type {AST.SvelteNode[][]} */
|
|
|
|
/** @type {AST.SvelteNode[][]} */
|
|
|
|
const items = [];
|
|
|
|
const items = [];
|
|
|
|
|
|
|
|
|
|
|
|
@ -459,6 +612,10 @@ const svelte_visitors = (comments) => ({
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
multiline ||= width > LINE_BREAK_THRESHOLD;
|
|
|
|
multiline ||= width > LINE_BREAK_THRESHOLD;
|
|
|
|
|
|
|
|
// Normally context.newline() also makes context.multiline true, but the below loop only
|
|
|
|
|
|
|
|
// does that if we have more than one child context. If there's one long text block inside
|
|
|
|
|
|
|
|
// with whitespace at the edges we wanna split that up, too.
|
|
|
|
|
|
|
|
context.multiline ||= has_surrounding_whitespace && width > LINE_BREAK_THRESHOLD * 2;
|
|
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < child_contexts.length; i += 1) {
|
|
|
|
for (let i = 0; i < child_contexts.length; i += 1) {
|
|
|
|
const prev = child_contexts[i];
|
|
|
|
const prev = child_contexts[i];
|
|
|
|
@ -525,7 +682,7 @@ const svelte_visitors = (comments) => ({
|
|
|
|
|
|
|
|
|
|
|
|
if (node.pending) {
|
|
|
|
if (node.pending) {
|
|
|
|
context.write('}');
|
|
|
|
context.write('}');
|
|
|
|
block(context, node.pending);
|
|
|
|
block(context, node.pending, state.preserve_whitespace > 0);
|
|
|
|
context.write('{:');
|
|
|
|
context.write('{:');
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
context.write(' ');
|
|
|
|
context.write(' ');
|
|
|
|
@ -536,7 +693,7 @@ const svelte_visitors = (comments) => ({
|
|
|
|
if (node.value) context.visit(node.value);
|
|
|
|
if (node.value) context.visit(node.value);
|
|
|
|
context.write('}');
|
|
|
|
context.write('}');
|
|
|
|
|
|
|
|
|
|
|
|
block(context, node.then);
|
|
|
|
block(context, node.then, state.preserve_whitespace > 0);
|
|
|
|
|
|
|
|
|
|
|
|
if (node.catch) {
|
|
|
|
if (node.catch) {
|
|
|
|
context.write('{:');
|
|
|
|
context.write('{:');
|
|
|
|
@ -548,7 +705,7 @@ const svelte_visitors = (comments) => ({
|
|
|
|
if (node.error) context.visit(node.error);
|
|
|
|
if (node.error) context.visit(node.error);
|
|
|
|
context.write('}');
|
|
|
|
context.write('}');
|
|
|
|
|
|
|
|
|
|
|
|
block(context, node.catch);
|
|
|
|
block(context, node.catch, state.preserve_whitespace > 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
context.write('{/await}');
|
|
|
|
context.write('{/await}');
|
|
|
|
@ -592,7 +749,7 @@ const svelte_visitors = (comments) => ({
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
Component(node, context) {
|
|
|
|
Component(node, context) {
|
|
|
|
base_element(node, context, comments);
|
|
|
|
print_element(node, context, comments, state);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
ConstTag(node, context) {
|
|
|
|
ConstTag(node, context) {
|
|
|
|
@ -682,11 +839,11 @@ const svelte_visitors = (comments) => ({
|
|
|
|
|
|
|
|
|
|
|
|
context.write('}');
|
|
|
|
context.write('}');
|
|
|
|
|
|
|
|
|
|
|
|
block(context, node.body);
|
|
|
|
block(context, node.body, state.preserve_whitespace > 0);
|
|
|
|
|
|
|
|
|
|
|
|
if (node.fallback) {
|
|
|
|
if (node.fallback) {
|
|
|
|
context.write('{:else}');
|
|
|
|
context.write('{:else}');
|
|
|
|
block(context, node.fallback);
|
|
|
|
block(context, node.fallback, state.preserve_whitespace > 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
context.write('{/each}');
|
|
|
|
context.write('{/each}');
|
|
|
|
@ -710,13 +867,13 @@ const svelte_visitors = (comments) => ({
|
|
|
|
context.visit(node.test);
|
|
|
|
context.visit(node.test);
|
|
|
|
context.write('}');
|
|
|
|
context.write('}');
|
|
|
|
|
|
|
|
|
|
|
|
block(context, node.consequent);
|
|
|
|
block(context, node.consequent, state.preserve_whitespace > 0);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
context.write('{#if ');
|
|
|
|
context.write('{#if ');
|
|
|
|
context.visit(node.test);
|
|
|
|
context.visit(node.test);
|
|
|
|
context.write('}');
|
|
|
|
context.write('}');
|
|
|
|
|
|
|
|
|
|
|
|
block(context, node.consequent);
|
|
|
|
block(context, node.consequent, state.preserve_whitespace > 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (node.alternate !== null) {
|
|
|
|
if (node.alternate !== null) {
|
|
|
|
@ -728,7 +885,7 @@ const svelte_visitors = (comments) => ({
|
|
|
|
)
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
context.write('{:else}');
|
|
|
|
context.write('{:else}');
|
|
|
|
block(context, node.alternate);
|
|
|
|
block(context, node.alternate, state.preserve_whitespace > 0);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
context.visit(node.alternate);
|
|
|
|
context.visit(node.alternate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -743,7 +900,7 @@ const svelte_visitors = (comments) => ({
|
|
|
|
context.write('{#key ');
|
|
|
|
context.write('{#key ');
|
|
|
|
context.visit(node.expression);
|
|
|
|
context.visit(node.expression);
|
|
|
|
context.write('}');
|
|
|
|
context.write('}');
|
|
|
|
block(context, node.fragment);
|
|
|
|
block(context, node.fragment, state.preserve_whitespace > 0);
|
|
|
|
context.write('{/key}');
|
|
|
|
context.write('{/key}');
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
@ -775,7 +932,7 @@ const svelte_visitors = (comments) => ({
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
RegularElement(node, context) {
|
|
|
|
RegularElement(node, context) {
|
|
|
|
base_element(node, context, comments);
|
|
|
|
print_element(node, context, comments, state);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
RenderTag(node, context) {
|
|
|
|
RenderTag(node, context) {
|
|
|
|
@ -785,7 +942,7 @@ const svelte_visitors = (comments) => ({
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
SlotElement(node, context) {
|
|
|
|
SlotElement(node, context) {
|
|
|
|
base_element(node, context, comments);
|
|
|
|
print_element(node, context, comments, state);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
SnippetBlock(node, context) {
|
|
|
|
SnippetBlock(node, context) {
|
|
|
|
@ -804,7 +961,7 @@ const svelte_visitors = (comments) => ({
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
context.write(')}');
|
|
|
|
context.write(')}');
|
|
|
|
block(context, node.body);
|
|
|
|
block(context, node.body, state.preserve_whitespace > 0);
|
|
|
|
context.write('{/snippet}');
|
|
|
|
context.write('{/snippet}');
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
@ -839,40 +996,12 @@ const svelte_visitors = (comments) => ({
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
StyleSheet(node, context) {
|
|
|
|
|
|
|
|
context.write('<style');
|
|
|
|
|
|
|
|
attributes(node, node.attributes, context, comments);
|
|
|
|
|
|
|
|
context.write('>');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (node.children.length > 0) {
|
|
|
|
|
|
|
|
context.indent();
|
|
|
|
|
|
|
|
context.newline();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let started = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const child of node.children) {
|
|
|
|
|
|
|
|
if (started) {
|
|
|
|
|
|
|
|
context.margin();
|
|
|
|
|
|
|
|
context.newline();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
context.visit(child);
|
|
|
|
|
|
|
|
started = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
context.dedent();
|
|
|
|
|
|
|
|
context.newline();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
context.write('</style>');
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SvelteBody(node, context) {
|
|
|
|
SvelteBody(node, context) {
|
|
|
|
base_element(node, context, comments);
|
|
|
|
print_element(node, context, comments, state);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
SvelteBoundary(node, context) {
|
|
|
|
SvelteBoundary(node, context) {
|
|
|
|
base_element(node, context, comments);
|
|
|
|
print_element(node, context, comments, state);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
SvelteComponent(node, context) {
|
|
|
|
SvelteComponent(node, context) {
|
|
|
|
@ -884,7 +1013,7 @@ const svelte_visitors = (comments) => ({
|
|
|
|
attributes(node, node.attributes, context, comments);
|
|
|
|
attributes(node, node.attributes, context, comments);
|
|
|
|
if (node.fragment && node.fragment.nodes.length > 0) {
|
|
|
|
if (node.fragment && node.fragment.nodes.length > 0) {
|
|
|
|
context.write('>');
|
|
|
|
context.write('>');
|
|
|
|
block(context, node.fragment, true);
|
|
|
|
block(context, node.fragment, state.preserve_whitespace > 0, true);
|
|
|
|
context.write(`</svelte:component>`);
|
|
|
|
context.write(`</svelte:component>`);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
context.write(' />');
|
|
|
|
context.write(' />');
|
|
|
|
@ -892,7 +1021,7 @@ const svelte_visitors = (comments) => ({
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
SvelteDocument(node, context) {
|
|
|
|
SvelteDocument(node, context) {
|
|
|
|
base_element(node, context, comments);
|
|
|
|
print_element(node, context, comments, state);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
SvelteElement(node, context) {
|
|
|
|
SvelteElement(node, context) {
|
|
|
|
@ -905,7 +1034,7 @@ const svelte_visitors = (comments) => ({
|
|
|
|
|
|
|
|
|
|
|
|
if (node.fragment && node.fragment.nodes.length > 0) {
|
|
|
|
if (node.fragment && node.fragment.nodes.length > 0) {
|
|
|
|
context.write('>');
|
|
|
|
context.write('>');
|
|
|
|
block(context, node.fragment);
|
|
|
|
block(context, node.fragment, state.preserve_whitespace > 0);
|
|
|
|
context.write(`</svelte:element>`);
|
|
|
|
context.write(`</svelte:element>`);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
context.write(' />');
|
|
|
|
context.write(' />');
|
|
|
|
@ -913,19 +1042,19 @@ const svelte_visitors = (comments) => ({
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
SvelteFragment(node, context) {
|
|
|
|
SvelteFragment(node, context) {
|
|
|
|
base_element(node, context, comments);
|
|
|
|
print_element(node, context, comments, state);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
SvelteHead(node, context) {
|
|
|
|
SvelteHead(node, context) {
|
|
|
|
base_element(node, context, comments);
|
|
|
|
print_element(node, context, comments, state);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
SvelteSelf(node, context) {
|
|
|
|
SvelteSelf(node, context) {
|
|
|
|
base_element(node, context, comments);
|
|
|
|
print_element(node, context, comments, state);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
SvelteWindow(node, context) {
|
|
|
|
SvelteWindow(node, context) {
|
|
|
|
base_element(node, context, comments);
|
|
|
|
print_element(node, context, comments, state);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
Text(node, context) {
|
|
|
|
Text(node, context) {
|
|
|
|
@ -933,7 +1062,7 @@ const svelte_visitors = (comments) => ({
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
TitleElement(node, context) {
|
|
|
|
TitleElement(node, context) {
|
|
|
|
base_element(node, context, comments);
|
|
|
|
print_element(node, context, comments, state);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
TransitionDirective(node, context) {
|
|
|
|
TransitionDirective(node, context) {
|
|
|
|
|