Files
test-repo/src/language-html/embed.js
T
Christian Zosel fac08034e7 Split out location extraction into plugin config (#3777)
* Split out location extraction into plugin config

* Reduce set of exported function, rebase to current master

* Pass custom locStart/locEnd fn's directly to affected methods

* (wip) always use locStart/locEnd from plugin

* Convert graphql implementation

* Convert HTML implementation

* (wip) convert JS implementation

* Remove unused variables

* Continue conversion of JS implementation

* Replace "util.locStart" with direct call to "options.locStart"

* Remove util closure

* Add unit test for structure of shared util

* Fix linting error, simplify locStart/End implementations
2018-02-09 23:17:48 +11:00

97 lines
2.6 KiB
JavaScript

"use strict";
const privateUtil = require("../common/util");
const doc = require("../doc");
const docUtils = doc.utils;
const docBuilders = doc.builders;
const hardline = docBuilders.hardline;
const concat = docBuilders.concat;
function embed(path, print, textToDoc, options) {
const node = path.getValue();
switch (node.type) {
case "text": {
const parent = path.getParentNode();
// Inline JavaScript
if (
parent.type === "script" &&
((!parent.attribs.lang && !parent.attribs.lang) ||
parent.attribs.type === "text/javascript" ||
parent.attribs.type === "application/javascript")
) {
const parser = options.parser === "flow" ? "flow" : "babylon";
const doc = textToDoc(getText(options, node), { parser });
return concat([hardline, doc]);
}
// Inline TypeScript
if (
parent.type === "script" &&
(parent.attribs.type === "application/x-typescript" ||
parent.attribs.lang === "ts")
) {
const doc = textToDoc(
getText(options, node),
{ parser: "typescript" },
options
);
return concat([hardline, doc]);
}
// Inline Styles
if (parent.type === "style") {
const doc = textToDoc(getText(options, node), { parser: "css" });
return concat([hardline, docUtils.stripTrailingHardline(doc)]);
}
break;
}
case "attribute": {
/*
* Vue binding sytax: JS expressions
* :class="{ 'some-key': value }"
* v-bind:id="'list-' + id"
* v-if="foo && !bar"
* @click="someFunction()"
*/
if (/(^@)|(^v-)|:/.test(node.key) && !/^\w+$/.test(node.value)) {
const doc = textToDoc(node.value, {
parser: parseJavaScriptExpression,
// Use singleQuote since HTML attributes use double-quotes.
// TODO(azz): We still need to do an entity escape on the attribute.
singleQuote: true
});
return concat([
node.key,
'="',
privateUtil.hasNewlineInRange(node.value, 0, node.value.length)
? doc
: docUtils.removeLines(doc),
'"'
]);
}
}
}
}
function parseJavaScriptExpression(text, parsers) {
// Force parsing as an expression
const ast = parsers.babylon(`(${text})`);
// Extract expression from the declaration
return {
type: "File",
program: ast.program.body[0].expression
};
}
function getText(options, node) {
return options.originalText.slice(
options.locStart(node),
options.locEnd(node)
);
}
module.exports = embed;