Skip to content

Commit

Permalink
Passthrough HTML attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
bobisjan committed Jan 22, 2022
1 parent b9f0f31 commit e50e940
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 3 deletions.
23 changes: 20 additions & 3 deletions packages/core/src/ember-html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ function immediatelyAfter(node: Node) {

export class PreparedEmberHTML {
dom: JSDOM;
origin: JSDOM;
javascript: NodeRange;
styles: NodeRange;
implicitScripts: NodeRange;
Expand All @@ -60,7 +61,9 @@ export class PreparedEmberHTML {
implicitTestStyles: NodeRange;

constructor(private asset: EmberAsset) {
this.dom = new JSDOM(readFileSync(asset.sourcePath, 'utf8'));
let source = readFileSync(asset.sourcePath, 'utf8');
this.dom = new JSDOM(source);
this.origin = new JSDOM(source);
let html = asset.prepare(this.dom);
this.javascript = new NodeRange(html.javascript);
this.styles = new NodeRange(html.styles);
Expand Down Expand Up @@ -97,7 +100,14 @@ export class PreparedEmberHTML {
// root-relative via the configured rootURL
insertScriptTag(location: NodeRange, relativeSrc: string, opts?: { type?: string; tag?: string }) {
let newTag = this.dom.window.document.createElement(opts && opts.tag ? opts.tag : 'script');
newTag.setAttribute('src', this.asset.rootURL + relativeSrc);
let src = this.asset.rootURL + relativeSrc;
let origin = this.origin.window.document.querySelector(`script[src="${src}"]`);
if (origin) {
for (let { name, value } of [...origin.attributes]) {
newTag.setAttribute(name, value);
}
}
newTag.setAttribute('src', src);
if (opts && opts.type) {
newTag.setAttribute('type', opts.type);
}
Expand All @@ -109,8 +119,15 @@ export class PreparedEmberHTML {
// root-relative via the configured rootURL
insertStyleLink(location: NodeRange, relativeHref: string) {
let newTag = this.dom.window.document.createElement('link');
let href = this.asset.rootURL + relativeHref;
let origin = this.origin.window.document.querySelector(`link[href="${href}"][rel="stylesheet"]`);
if (origin) {
for (let { name, value } of [...origin.attributes]) {
newTag.setAttribute(name, value);
}
}
newTag.rel = 'stylesheet';
newTag.href = this.asset.rootURL + relativeHref;
newTag.href = href;
location.insert(this.dom.window.document.createTextNode('\n'));
location.insert(newTag);
}
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/html-placeholder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ export default class Placeholder {

insertStyleLink(href: string) {
let newTag = this.end.ownerDocument.createElement('link');
for (let { name, value } of [...this.target.attributes]) {
newTag.setAttribute(name, value);
}
newTag.href = href;
newTag.rel = 'stylesheet';

Expand Down
25 changes: 25 additions & 0 deletions tests/fixtures/html-attributes-app/app/indexl.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>AppTemplate</title>
<meta name="description" content="" />
<meta name="viewport" content="width=device-width, initial-scale=1" />

{{content-for "head"}}

<link integrity="" rel="stylesheet" href="{{rootURL}}assets/vendor.css" data-testid="custom-vendor-style-attr" />
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/app-template.css" data-testid="custom-app-style-attr" />

{{content-for "head-footer"}}
</head>
<body>
{{content-for "body"}}

<script src="{{rootURL}}assets/vendor.js" data-testid="custom-vendor-script-attr"></script>
<script src="{{rootURL}}assets/app-template.js" data-testid="custom-vendor-script-attr"></script>

{{content-for "body-footer"}}
</body>
</html>
34 changes: 34 additions & 0 deletions tests/scenarios/build-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { appScenarios } from './scenarios';
import { PreparedApp } from 'scenario-tester';
import QUnit from 'qunit';
import merge from 'lodash/merge';
import { join } from 'path';
import { loadFromFixtureData } from './helpers';
import fs from 'fs-extra';
const { module: Qmodule, test } = QUnit;

appScenarios
.map('html-attributes-tests', project => {
merge(project.files, loadFromFixtureData('html-attributes-app'));
})
.forEachScenario(scenario => {
Qmodule(scenario.name, function (hooks) {
let app: PreparedApp;

hooks.before(async () => {
app = await scenario.prepare();
});

test(`index.html contains custom attributes`, async function (assert) {
let result = await app.execute(`cross-env THROW_UNLESS_PARALLELIZABLE=1 yarn build:production`);
assert.equal(result.exitCode, 0, result.output);

let fileContents = fs.readFileSync(join(app.dir, 'dist', 'index.html'));

assert.ok(fileContents.includes('data-testid="custom-vendor-style-attr"'), 'custom attr for vendor style');
assert.ok(fileContents.includes('data-testid="custom-app-style-attr"'), 'custom attr for app style');
assert.ok(fileContents.includes('data-testid="custom-vendor-script-attr"'), 'custom attr for vendor script');
assert.ok(fileContents.includes('data-testid="custom-vendor-script-attr"'), 'custom attr for app script');
});
});
});

0 comments on commit e50e940

Please sign in to comment.