Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

report: source-location for linkifying #9354

Merged
merged 64 commits into from
Nov 20, 2019
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
ba10b4d
first pass
connorjclark Jul 10, 2019
4b139e5
next pass
connorjclark Jul 10, 2019
dd1a015
comment
connorjclark Jul 11, 2019
771f4d2
use source column
connorjclark Jul 11, 2019
35ee4a8
Merge remote-tracking branch 'origin/master' into ui-location-details
connorjclark Jul 11, 2019
1aff81c
un comment code
connorjclark Jul 11, 2019
d2f5901
delete old code
connorjclark Jul 11, 2019
2b7c535
add inline/attribute decl back
connorjclark Jul 12, 2019
d958a06
add dynamic
connorjclark Jul 12, 2019
b60ac0c
just dynamic
connorjclark Jul 12, 2019
1d6e180
Merge remote-tracking branch 'origin/master' into ui-location-details
connorjclark Jul 18, 2019
48fc734
use details types
connorjclark Jul 18, 2019
55351b2
fix test
connorjclark Jul 18, 2019
a27662a
fix ts
connorjclark Jul 18, 2019
e9ba60b
tests
connorjclark Jul 18, 2019
320b28f
source-location
connorjclark Jul 18, 2019
a3fe3e9
only line+1 for view
connorjclark Jul 18, 2019
06ebc59
magic comment test
connorjclark Jul 18, 2019
87ef6c8
comment
connorjclark Jul 18, 2019
193a01f
comment
connorjclark Jul 18, 2019
fe3ded1
better handling of source url comment
connorjclark Jul 18, 2019
51a8261
lint
connorjclark Jul 18, 2019
87813ce
fix smoke
connorjclark Jul 18, 2019
1fb1c60
isLink -> canLink
connorjclark Jul 18, 2019
ddec94d
do not use line/col in the anchor href
connorjclark Jul 18, 2019
a3bb066
tag from srouceURL
connorjclark Jul 18, 2019
d04bc12
update sample json
connorjclark Jul 18, 2019
8036b81
urlIsNetworkResource
connorjclark Jul 18, 2019
6cdfa33
decompose test
connorjclark Jul 18, 2019
1062f41
Merge remote-tracking branch 'origin/master' into ui-location-details
connorjclark Jul 18, 2019
e97891f
words--
connorjclark Jul 18, 2019
8cca543
add details renderer test
connorjclark Jul 18, 2019
9ecc815
test
connorjclark Jul 18, 2019
634a295
Merge remote-tracking branch 'origin/master' into ui-location-details
connorjclark Jul 18, 2019
8bf0153
tests
connorjclark Jul 18, 2019
5abf748
styles
connorjclark Jul 19, 2019
cf4eef2
Update lighthouse-core/audits/seo/font-size.js
connorjclark Jul 20, 2019
c7cbd2a
comment
connorjclark Jul 23, 2019
bf819d2
comment
connorjclark Jul 23, 2019
6bb5007
Merge remote-tracking branch 'origin/master' into ui-location-details
connorjclark Jul 23, 2019
4af5aad
fix test
connorjclark Jul 23, 2019
c29e9cb
lint
connorjclark Jul 24, 2019
9295fc0
Update lighthouse-core/audits/seo/font-size.js
connorjclark Aug 14, 2019
b879e84
use source-location in deprecations audit
connorjclark Aug 15, 2019
75ef6ba
urlProvider
connorjclark Aug 15, 2019
1e9abab
fix test
connorjclark Aug 15, 2019
c1aa17a
fix test
connorjclark Aug 15, 2019
cd66b45
fix test
connorjclark Aug 15, 2019
aec3484
fix test
connorjclark Aug 15, 2019
a16756e
sample
connorjclark Aug 15, 2019
d2c6b60
Merge remote-tracking branch 'origin/master' into ui-location-details
connorjclark Aug 15, 2019
7c28493
Merge remote-tracking branch 'origin/master' into ui-location-details
connorjclark Aug 30, 2019
a62e34c
Update lighthouse-core/report/html/renderer/details-renderer.js
connorjclark Aug 31, 2019
eae758c
'ui-location-details' of github.com:GoogleChrome/lighthouse into ui…
connorjclark Aug 31, 2019
30a7daf
toString
connorjclark Aug 31, 2019
f9de084
namespace data attrs
connorjclark Aug 31, 2019
f75e251
table null->undefined
connorjclark Aug 31, 2019
96c7d3e
comment
connorjclark Aug 31, 2019
a8c5655
Revert "toString"
connorjclark Aug 31, 2019
386a654
fix jsdoc
connorjclark Aug 31, 2019
b26d9c0
fix depr ts
connorjclark Aug 31, 2019
2274114
Merge remote-tracking branch 'origin/master' into ui-location-details
connorjclark Sep 6, 2019
6f38744
fix sample
connorjclark Sep 6, 2019
56eb6c0
Merge remote-tracking branch 'origin/master' into ui-location-details
connorjclark Nov 19, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 42 additions & 36 deletions lighthouse-core/audits/seo/font-size.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,64 +121,70 @@ function nodeToTableNode(node) {
* @param {string} baseURL
* @param {FailingNodeData['cssRule']} styleDeclaration
* @param {FailingNodeData['node']} node
* @returns {{source: string, selector: string | {type: 'node', selector: string, snippet: string}}}
* @returns {{source: {type: 'url', value: string} | {type: 'ui-location', sourceURL?: string, url: string, line: number, column: number} | {type: 'code', value: string}, selector: string | {type: 'node', selector: string, snippet: string}}}
*/
function findStyleRuleSource(baseURL, styleDeclaration, node) {
if (
!styleDeclaration ||
if (!styleDeclaration ||
styleDeclaration.type === 'Attributes' ||
styleDeclaration.type === 'Inline'
) {
return {
source: {type: 'url', value: baseURL},
selector: nodeToTableNode(node),
source: baseURL,
};
}

if (styleDeclaration.parentRule &&
styleDeclaration.parentRule.origin === 'user-agent') {
return {
source: {type: 'code', value: 'User Agent Stylesheet'},
selector: styleDeclaration.parentRule.selectors.map(item => item.text).join(', '),
source: 'User Agent Stylesheet',
};
}

if (styleDeclaration.type === 'Regular' && styleDeclaration.parentRule) {
let selector = '';
if (styleDeclaration.parentRule) {
const rule = styleDeclaration.parentRule;
const stylesheet = styleDeclaration.stylesheet;

if (stylesheet) {
let source;
const selector = rule.selectors.map(item => item.text).join(', ');

if (stylesheet.sourceURL) {
const url = new URL(stylesheet.sourceURL, baseURL);
const range = styleDeclaration.range;
source = `${url.href}`;
selector = rule.selectors.map(item => item.text).join(', ');
}

if (range) {
// `stylesheet` can be either an external file (stylesheet.startLine will always be 0),
// or a <style> block (stylesheet.startLine will vary)
const absoluteStartLine = range.startLine + stylesheet.startLine + 1;
const absoluteStartColumn = range.startColumn + stylesheet.startColumn + 1;
if (styleDeclaration.stylesheet && !styleDeclaration.stylesheet.sourceURL) {
return {
source: {type: 'code', value: 'dynamic'},
selector,
};
}

source += `:${absoluteStartLine}:${absoluteStartColumn}`;
}
} else {
// dynamically injected to page
source = 'dynamic';
if (styleDeclaration.range) {
// The magic comment sourceURL, if any. Used to resolve a url relative to the baseUrl.
// Note, URLs resolved from a magic comment aren't expected to _actually_ exist ...
const sourceURL = styleDeclaration.stylesheet ? styleDeclaration.stylesheet.sourceURL : '';
const url = new URL(sourceURL, baseURL).href;
// TODO when is `styleDeclaration.range` null ???
let {startLine, startColumn} = styleDeclaration.range ? styleDeclaration.range : {startLine: 0, startColumn: 0};

// Inline elements need to add the startLine/startColumn of the <script> element to the ui location, so that the location
// is relevant to the HTML file the stylesheet is within.
// But, if an inline stylesheet has a sourceURL magic comment, `hasSourceURL` is true and thus `styleDeclaration.range` is sufficient.
if (styleDeclaration.stylesheet && styleDeclaration.stylesheet.isInline && !styleDeclaration.stylesheet.hasSourceURL) {
startLine += styleDeclaration.stylesheet.startLine;
// The column the stylesheet begins on is only relevant if the rule is declared on the same line.
// `<div>...</div><style>.some-rule{}`
if (styleDeclaration.range && styleDeclaration.range.startLine === 0) {
startColumn += styleDeclaration.stylesheet.startColumn;
}

return {
selector,
source,
};
}

const magicCommentSourceUrl = styleDeclaration.stylesheet && styleDeclaration.stylesheet.hasSourceURL ? sourceURL : undefined;
return {
source: {type: 'ui-location', sourceURL: magicCommentSourceUrl, url, line: startLine, column: startColumn},
selector,
};
}

return {
selector: '',
source: 'Unknown',
selector,
source: {type: 'code', value: 'Unknown'},
};
}

Expand Down Expand Up @@ -254,7 +260,7 @@ class FontSize extends Audit {

/** @type {LH.Audit.Details.Table['headings']} */
const headings = [
{key: 'source', itemType: 'url', text: 'Source'},
{key: 'source', itemType: 'ui-location', text: 'Source'},
{key: 'selector', itemType: 'code', text: 'Selector'},
{key: 'coverage', itemType: 'text', text: '% of Page Text'},
{key: 'fontSize', itemType: 'text', text: 'Font Size'},
Expand All @@ -279,7 +285,7 @@ class FontSize extends Audit {
(failingTextLength - analyzedFailingTextLength) / visitedTextLength * 100;

tableData.push({
source: 'Add\'l illegible text',
source: {type: 'code', value: 'Add\'l illegible text'},
selector: '',
coverage: `${percentageOfUnanalyzedFailingText.toFixed(2)}%`,
fontSize: '< 12px',
Expand All @@ -288,7 +294,7 @@ class FontSize extends Audit {

if (percentageOfPassingText > 0) {
tableData.push({
source: 'Legible text',
source: {type: 'code', value: 'Legible text'},
selector: '',
coverage: `${percentageOfPassingText.toFixed(2)}%`,
fontSize: '≥ 12px',
Expand Down
20 changes: 19 additions & 1 deletion lighthouse-core/report/html/renderer/details-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ class DetailsRenderer {

/**
* @param {string} text
* @return {HTMLElement}
*/
renderTextURL(text) {
const url = text;
Expand Down Expand Up @@ -214,6 +213,9 @@ class DetailsRenderer {
case 'node': {
return this.renderNode(value);
}
case 'ui-location': {
return this.renderUILocation(value);
}
case 'url': {
return this.renderTextURL(value.value);
}
Expand Down Expand Up @@ -377,6 +379,22 @@ class DetailsRenderer {
return element;
}

/**
* @param {LH.Audit.Details.UILocationValue} item
* @return {Element}
* @protected
*/
renderUILocation(item) {
// TODO use source map
const element = this.renderTextURL(`${item.url}:${item.line + 1}:${item.column}`);
element.classList.add('lh-ui-location__location');
// TODO: remove sourceURL. see comment on UILocationValue doc.
element.setAttribute('data-url', item.sourceURL || item.url);
element.setAttribute('data-line', String(item.line));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think .toString() is a little favored over using the constructor.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fyi this file uses String() a few times but never toString

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fyi this file uses String() a few times but never toString

yeah, I don't know how that happened in here but generally good to stick with the ambient style

Copy link
Collaborator Author

@connorjclark connorjclark Aug 31, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed to toString()

note, if a plugin happens to provide a bad value (or no value) here, it would now error the renderer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I was agreeing with you that String() is fine in here since it's the established style

(there's only so much we can do against a plugin that refuses to use our types, though. you don't even need a plugin, you could just save a bad lhr to a gist and load it in the viewer)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, reverted.

element.setAttribute('data-column', String(item.column));
return element;
}

/**
* @param {LH.Audit.Details.Filmstrip} details
* @return {Element}
Expand Down
11 changes: 8 additions & 3 deletions lighthouse-core/report/html/renderer/report-ui-features.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ class ReportUIFeatures {
/** @type {Array<HTMLTableElement>} */
const tables = Array.from(this._document.querySelectorAll('.lh-table'));
const tablesWithUrls = tables
.filter(el => el.querySelector('td.lh-table-column--url'))
.filter(el => el.querySelector('td.lh-table-column--url, td.lh-table-column--ui-location'))
.filter(el => {
const containingAudit = el.closest('.lh-audit');
if (!containingAudit) throw new Error('.lh-table not within audit');
Expand Down Expand Up @@ -292,8 +292,13 @@ class ReportUIFeatures {
for (const urlItem of urlItems) {
const datasetUrl = urlItem.dataset.url;
if (!datasetUrl) continue;
const isThirdParty = Util.getRootDomain(datasetUrl) !== finalUrlRootDomain;
if (!isThirdParty) continue;
try {
const isThirdParty = Util.getRootDomain(datasetUrl) !== finalUrlRootDomain;
if (!isThirdParty) continue;
} catch (err) {
// Invalid url (from sourceURL magic comment). Assume 1p.
continue;
}

const urlRowEl = urlItem.closest('tr');
if (urlRowEl) {
Expand Down
4 changes: 3 additions & 1 deletion lighthouse-core/report/html/report-styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -973,7 +973,8 @@
font-size: large;
}

.lh-code {
.lh-code,
.lh-ui-location {
white-space: normal;
margin-top: 0;
font-size: 85%;
Expand Down Expand Up @@ -1330,6 +1331,7 @@

/* Looks unnecessary, but mostly for keeping the <th>s left-aligned */
.lh-table-column--text,
.lh-table-column--ui-location,
.lh-table-column--url,
/* .lh-table-column--thumbnail, */
/* .lh-table-column--empty,*/
Expand Down
6 changes: 3 additions & 3 deletions lighthouse-core/scripts/roll-to-devtools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ else
frontend_dir="$chromium_dir/third_party/blink/renderer/devtools/front_end"
fi

tests_dir="$frontend_dir/../../../web_tests/http/tests/devtools/audits2"
tests_dir="$frontend_dir/../../../web_tests/http/tests/devtools/audits"

if [[ ! -d "$frontend_dir" || ! -a "$frontend_dir/Runtime.js" ]]; then
echo -e "\033[31m✖ Error!\033[39m"
Expand All @@ -43,10 +43,10 @@ cp -pPR "$lh_bg_js" "$lh_worker_dir/lighthouse-dt-bundle.js"
echo -e "\033[96m ✓\033[39m (Potentially stale) lighthouse-dt-bundle copied."

# copy report generator + cached resources into $fe_lh_dir
cp -r dist/dt-report-resources/ $fe_lh_dir
cp -r dist/dt-report-resources/* $fe_lh_dir

# update expected version string in tests
VERSION=$(node -e "console.log(require('./package.json').version)")
sed -i '' -e "s/Version:.*/Version: $VERSION/g" "$tests_dir"/*-expected.txt

echo "Done. To rebase the test expectations, run: yarn --cwd ~/chromium/src/third_party/blink/renderer/devtools test 'http/tests/devtools/audits2/*' --reset-results"
echo "Done. To rebase the test expectations, run: yarn --cwd ~/chromium/src/third_party/blink/renderer/devtools test 'http/tests/devtools/audits/*' --reset-results"
21 changes: 19 additions & 2 deletions types/audit-details.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ declare global {
}

/** Possible types of values found within table items. */
type ItemValueTypes = 'bytes' | 'code' | 'link' | 'ms' | 'node' | 'numeric' | 'text' | 'thumbnail' | 'timespanMs' | 'url';
type ItemValueTypes = 'bytes' | 'code' | 'link' | 'ms' | 'node' | 'ui-location' | 'numeric' | 'text' | 'thumbnail' | 'timespanMs' | 'url';

// TODO(bckenny): unify Table/Opportunity headings and items on next breaking change.

Expand All @@ -104,7 +104,7 @@ declare global {

export type TableItem = {
debugData?: DebugData;
[p: string]: string | number | boolean | undefined | DebugData | NodeValue | LinkValue | UrlValue | CodeValue;
[p: string]: string | number | boolean | undefined | DebugData | NodeValue | UILocationValue | LinkValue | UrlValue | CodeValue;
}

export interface OpportunityColumnHeading {
Expand Down Expand Up @@ -167,6 +167,23 @@ declare global {
nodeLabel?: string;
}

export interface UILocationValue {
type: 'ui-location';
/** TODO: remove `sourceURL`.
* It's only necessary for the case where a file has a magic sourceURL comment.
* Since `url` is made with the surrounding source file's URL as the base URL (new URL(sourceURL, baseURL).href),
* the url will be `http://localhost:8000/filenameFromSourceURLComment.css` instead of `filenameFromSourceURLComment.css`.
* When DevTools tries to linkify the former, it does so as if it's an actual URL and fails to link to the file in Sources.
* The latter works fine.
*
* Workaround: use `sourceURL` if defined for the data-url, else use `url`.
*/
sourceURL: string;
url: string;
line: number;
column: number;
}

/**
* A value used within a details object, intended to be displayed as a
* linkified URL, regardless of the controlling heading's valueType.
Expand Down