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

new_audit(plugins): avoid plugins #4218

Merged
merged 3 commits into from
Jan 10, 2018
Merged

Conversation

kdzwinel
Copy link
Collaborator

@kdzwinel kdzwinel commented Jan 9, 2018

Fixes #3180

Success:
plugins_success

Failure:
screen shot 2018-01-09 at 01 36 16

As I found out, world of embedding external content is very messy. There are many non-standard ways of embedding that still work (multiplied by the number of different browsers 😵).

My approach here was to focus on documented ways of embedding (docs from adobe, ms, oracle, mdn) and real-life uses on popular sites (video, games, showcases). It should cover most of the real-life uses, but I'm pretty sure there are some false positives and false negatives.

Some notes:

  • it's common to do feature detection when embedding such content (esp. for flash with swfobject.js, but there is also silverlight.js and some code from oracle doing the same for java). We won't be able to detect that unless user has these plugins enabled.
  • flash is often embedded as <object …><embed …></object>. I'm listing both the object and embed as separate entries on the details list as they potentially can have different contents.

Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

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

nicely done! very thorough as always 😄

const JAVA_BEAN_TYPE = 'application/x-java-bean';
const TYPE_BLOCKLIST = new Set([
'application/x-shockwave-flash',
// https://docs.oracle.com/cd/E19683-01/816-0378/using_tags/index.html
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: at a quick scan I thought these were part of the blocklist, maybe throw a "// See ..." in front of there?

*/
function isPluginURL(url) {
try {
const filePath = new URL(url, 'http://example.com').pathname;
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: throw a comment here that we need example.com to support relative URLs, almost looks like a bug at first :)

category: 'Content Best Practices',
name: 'plugins',
description: 'Document avoids plugins.',
failureDescription: 'Document doesn\'t avoid plugins',
Copy link
Collaborator

Choose a reason for hiding this comment

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

the double negative gets a bit wonky, wdyt about Document uses plugins I only found one other case of the "doesn't avoid" we should fix

the overall pattern we favor elsewhere seems to be just Avoids plugins and Uses plugins

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Agreed, and since Rick also OKed it, I changed it to Document uses plugins as suggested.

}

const failingParams = item.params.filter(param =>
SOURCE_PARAMS.has(param.name.trim().toLowerCase()) && isPluginURL(param.value)
Copy link
Collaborator

Choose a reason for hiding this comment

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

is a param always guaranteed to have a name and value? if not let's either guard these accesses or throw each item into a try/catch we can recover from or maybe we can just do an || '' in the gatherer

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good catch - these can be nulls. I updated the gatherer.

}
}

module.exports = ExternalContent;
Copy link
Collaborator

Choose a reason for hiding this comment

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

🚲 🏠 I'm not 100% sold on ExternalContent, wdyt about EmbeddedContent?

MDN seems like it goes back and forth but titles it "Multimedia and embedding" https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies

Copy link
Collaborator Author

@kdzwinel kdzwinel left a comment

Choose a reason for hiding this comment

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

@patrickhulce All feedback addressed! Thank you for a super-quick response on this ⚡️

category: 'Content Best Practices',
name: 'plugins',
description: 'Document avoids plugins.',
failureDescription: 'Document doesn\'t avoid plugins',
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Agreed, and since Rick also OKed it, I changed it to Document uses plugins as suggested.

}

const failingParams = item.params.filter(param =>
SOURCE_PARAMS.has(param.name.trim().toLowerCase()) && isPluginURL(param.value)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good catch - these can be nulls. I updated the gatherer.

Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

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

looks a-ok by me! over to @paulirish if his knowledge on plugins is much better than mine 😄

*/
static get meta() {
return {
category: 'Content Best Practices',
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we've fully nixed category at this point, so should be safe to remove :)

}, '');
const params = plugin.params
.filter(param => SOURCE_PARAMS.has(param.name.trim().toLowerCase()))
.map(param => `<param ${param.name}="${param.value}" />`)
Copy link
Member

Choose a reason for hiding this comment

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

technically its not
<param ${param.name}="${param.value}" />
but
<param name="${param.name}" value="${param.value}" />

but since we're already simplifying the display of these elements, i don't really think it's too important. ;)

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, good catch! I agree that we are already simplifying, but it might be a bit too much. I'd change it to <param name="${param.name}" value="${param.value}" />

description: 'Document avoids plugins.',
failureDescription: 'Document uses plugins',
helpText: 'Some types of media or content are not playable on mobile devices. ' +
'[Learn more](https://developers.google.com/speed/docs/insights/AvoidPlugins).',
Copy link
Member

Choose a reason for hiding this comment

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

This URL is a dead 404 now, and I can't find a true replacement. MFT says this:
image

cached link is https://webcache.googleusercontent.com/search?q=cache:rke54rGwIMcJ:https://developers.google.com/speed/docs/insights/AvoidPlugins+&cd=1&hl=en&ct=clnk&gl=us

also https://developers.google.com/speed/docs/insights/UseLegibleFontSizes is gone, but they set up a redirect to WF.

@rviscomi do you have a preference where this links to? (i cc'd you on the recent CL where these docs were removed)

Copy link
Member

Choose a reason for hiding this comment

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

Ideally we'd make a new doc on https://developers.google.com/web/tools/lighthouse/. I'd be ok removing "Learn more" from the help text for now until we have that doc online.

Copy link
Member

Choose a reason for hiding this comment

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

WFM!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I double checked that URL when I opened this PR (a day ago) and it was up ¯\_(ツ)_/¯

Copy link
Member

Choose a reason for hiding this comment

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

yeah i looked and they had made the change this week. :)

name: 'plugins',
description: 'Document avoids plugins.',
failureDescription: 'Document uses plugins',
helpText: 'Some types of media or content are not playable on mobile devices. ' +
Copy link
Member

Choose a reason for hiding this comment

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

'Some types of media or content are not playable on mobile devices.'
=>
Most mobile devices do not support plugins, and many desktop browsers restrict them.

});

const headings = [
{key: 'source', itemType: 'code', text: 'Source'},
Copy link
Member

Choose a reason for hiding this comment

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

Source => Element source

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Just a note: we are already using 'Source' in hreflang and is-crawlable

Copy link
Member

@paulirish paulirish left a comment

Choose a reason for hiding this comment

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

LGTM. I'll address my comments myself. ;)

@paulirish paulirish merged commit 8436c03 into GoogleChrome:master Jan 10, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants