Skip to content
This repository has been archived by the owner on Jan 11, 2023. It is now read-only.

Commit

Permalink
Add parser support for HTML files (#2810)
Browse files Browse the repository at this point in the history
* add parser support for HTML files

* add test and fixture for parsing script in HTML files
  • Loading branch information
ryanjduffy authored and jasonLaster committed May 5, 2017
1 parent f9e048a commit 570fb08
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 13 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"md5": "^2.2.1",
"mocha": "^3.1.2",
"mock-require": "^2.0.2",
"parse-script-tags": "^0.1.1",
"prettier": "^1.3.0",
"pretty-fast": "^0.2.0",
"react": "=15.3.2",
Expand Down
30 changes: 21 additions & 9 deletions src/utils/parser/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const { isDevelopment } = require("devtools-config");
const toPairs = require("lodash/toPairs");
const isEmpty = require("lodash/isEmpty");
const uniq = require("lodash/uniq");
import parseScriptTags from "parse-script-tags";

import type { SourceText, Location, Frame, TokenResolution } from "../../types";

Expand Down Expand Up @@ -52,22 +53,24 @@ type Scope = {
bindings: Object[]
};

function _parse(code) {
return babylon.parse(code, {
sourceType: "module",

plugins: ["jsx", "flow"]
});
function _parse(code, opts) {
return babylon.parse(
code,
Object.assign({}, opts, {
sourceType: "module",
plugins: ["jsx", "flow"]
})
);
}

function parse(text: string) {
function parse(text: string, opts?: Object) {
let ast;
if (!text) {
return;
}

try {
ast = _parse(text);
ast = _parse(text, opts);
} catch (error) {
if (isDevelopment()) {
console.warn("parse failed", text);
Expand All @@ -85,7 +88,16 @@ function getAst(sourceText: SourceText) {
}

let ast = {};
if (sourceText.contentType == "text/javascript") {
if (sourceText.contentType == "text/html") {
// Custom parser for parse-script-tags that adapts its input structure to
// our parser's signature
const parser = ({ source, line }) => {
return parse(source, {
startLine: line
});
};
ast = parseScriptTags(sourceText.text, parser) || {};
} else if (sourceText.contentType == "text/javascript") {
ast = parse(sourceText.text);
}

Expand Down
42 changes: 42 additions & 0 deletions src/utils/tests/fixtures/parseScriptTags.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<html>
<head>
<script type="text/javascript">
var globalObject = {
first: "name",
last: "words"
};
function sayHello (name) {
return `Hello, ${name}!`;
}
</script>
<style>
BODY {
font-size: 48px;
color: rebeccapurple;
}
</style>
</head>
<body>
<h1>Testing Script Tags in HTML</h1>
<script>
const capitalize = name => {
return name[0].toUpperCase() + name.substring(1)
};
const greetAll = ["my friend", "buddy", "world"]
.map(capitalize)
.map(sayHello)
.join("\n");

globalObject.greetings = greetAll;
</script>
<p>
Some arbitrary intermediate content to affect the offsets of the scripts
</p>
<script>
(function iife() {
const greeting = sayHello("Ryan");
console.log(greeting);
})();
</script>
</body>
</html>
30 changes: 26 additions & 4 deletions src/utils/tests/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@ import {
const fs = require("fs");
const path = require("path");

function getSourceText(name) {
function getSourceText(name, type = "js") {
const text = fs.readFileSync(
path.join(__dirname, `fixtures/${name}.js`),
path.join(__dirname, `fixtures/${name}.${type}`),
"utf8"
);
const contentType = type === "html" ? "text/html" : "text/javascript";
return {
id: name,
text: text,
contentType: "text/javascript"
text,
contentType
};
}

Expand Down Expand Up @@ -98,6 +99,27 @@ describe("parser", () => {
});
});

describe("getSymbols -> <script> content", () => {
it("finds function, variable and class declarations", () => {
const allSymbols = getSymbols(getSourceText("parseScriptTags", "html"));
expect(allSymbols.functions.map(f => f.value)).to.eql([
"sayHello",
"capitalize",
"iife"
]);
expect(allSymbols.variables.map(v => v.value)).to.eql([
"globalObject",
"first",
"last",
"name",
"capitalize",
"name",
"greetAll",
"greeting"
]);
});
});

describe("getClosestExpression", () => {
it("Can find a member expression", () => {
const expression = getClosestExpression(
Expand Down
7 changes: 7 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5793,6 +5793,13 @@ parse-json@^2.1.0, parse-json@^2.2.0:
dependencies:
error-ex "^1.2.0"

parse-script-tags@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/parse-script-tags/-/parse-script-tags-0.1.1.tgz#db0b4dbe551e946055133c323ed8bcc0e6de6ab7"
dependencies:
babel-types "^6.24.1"
babylon "^6.17.0"

parse-url@^1.3.0:
version "1.3.7"
resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-1.3.7.tgz#636cb6e32b88255c704e30ab4349676703267af8"
Expand Down

0 comments on commit 570fb08

Please sign in to comment.