Skip to content

Commit

Permalink
refactor: split report-renderer into multiple files (#1987)
Browse files Browse the repository at this point in the history
* refactor: split report-renderer into multiple files

* added details renderer test

* fix closure scope
  • Loading branch information
patrickhulce committed Apr 12, 2017
1 parent 87bd052 commit 605a457
Show file tree
Hide file tree
Showing 7 changed files with 438 additions and 204 deletions.
91 changes: 91 additions & 0 deletions lighthouse-core/report/v2/renderer/details-renderer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* Copyright 2017 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';

class DetailsRenderer {
/**
* @param {!DOM} dom
*/
constructor(dom) {
this._dom = dom;
}

/**
* @param {!DetailsJSON} details
* @return {!Element}
*/
render(details) {
switch (details.type) {
case 'text':
return this._renderText(details);
case 'block':
return this._renderBlock(details);
case 'list':
return this._renderList(details);
default:
throw new Error(`Unknown type: ${details.type}`);
}
}

/**
* @param {!DetailsJSON} text
* @return {!Element}
*/
_renderText(text) {
const element = this._dom.createElement('div', 'lighthouse-text');
element.textContent = text.text;
return element;
}

/**
* @param {!DetailsJSON} block
* @return {!Element}
*/
_renderBlock(block) {
const element = this._dom.createElement('div', 'lighthouse-block');
for (const item of block.items) {
element.appendChild(this.render(item));
}
return element;
}

/**
* @param {!DetailsJSON} list
* @return {!Element}
*/
_renderList(list) {
const element = this._dom.createElement('details', 'lighthouse-list');
if (list.header) {
const summary = this._dom.createElement('summary', 'lighthouse-list__header');
summary.textContent = list.header.text;
element.appendChild(summary);
}

const items = this._dom.createElement('div', 'lighthouse-list__items');
for (const item of list.items) {
items.appendChild(this.render(item));
}
element.appendChild(items);
return element;
}
}

if (typeof module !== 'undefined' && module.exports) {
module.exports = DetailsRenderer;
}

/** @typedef {{type: string, text: string|undefined, header: DetailsJSON|undefined, items: Array<DetailsJSON>|undefined}} */
DetailsRenderer.DetailsJSON; // eslint-disable-line no-unused-expressions
90 changes: 90 additions & 0 deletions lighthouse-core/report/v2/renderer/dom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
* Copyright 2017 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';

/* globals URL */

class DOM {
/**
* @param {!Document} document
*/
constructor(document) {
this._document = document;
}

/**
* @param {string} name
* @param {string=} className
* @param {!Object<string, string>=} attrs Attribute key/val pairs.
* @return {!Element}
*/
createElement(name, className, attrs = {}) {
const element = this._document.createElement(name);
if (className) {
element.className = className;
}
Object.keys(attrs).forEach(key => {
element.setAttribute(key, attrs[key]);
});
return element;
}

/**
* @param {string} selector
* @return {!DocumentFragment} A clone of the template content.
* @throws {Error}
*/
cloneTemplate(selector) {
const template = this._document.querySelector(selector);
if (!template) {
throw new Error(`Template not found: template${selector}`);
}
return this._document.importNode(template.content, true);
}

/**
* @param {string} text
* @return {!HTMLSpanElement}
*/
createSpanFromMarkdown(text) {
const element = this.createElement('span');

// Split on markdown links (e.g. [some link](https://...)).
const parts = text.split(/\[(.*?)\]\((https?:\/\/.*?)\)/g);

while (parts.length) {
// Pop off the same number of elements as there are capture groups.
const [preambleText, linkText, linkHref] = parts.splice(0, 3);
element.appendChild(this._document.createTextNode(preambleText));

// Append link if there are any.
if (linkText && linkHref) {
const a = this.createElement('a');
a.rel = 'noopener';
a.target = '_blank';
a.textContent = linkText;
a.href = (new URL(linkHref)).href;
element.appendChild(a);
}
}

return element;
}
}

if (typeof module !== 'undefined' && module.exports) {
module.exports = DOM;
}
Loading

0 comments on commit 605a457

Please sign in to comment.