-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
Conversation
There was a problem hiding this 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 |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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', |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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
There was a problem hiding this 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', |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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.
There was a problem hiding this 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', |
There was a problem hiding this comment.
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}" />`) |
There was a problem hiding this comment.
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. ;)
There was a problem hiding this comment.
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).', |
There was a problem hiding this comment.
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:
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)
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WFM!
There was a problem hiding this comment.
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 ¯\_(ツ)_/¯
There was a problem hiding this comment.
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. ' + |
There was a problem hiding this comment.
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'}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Source => Element source
There was a problem hiding this comment.
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
There was a problem hiding this 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. ;)
Fixes #3180
Success:

Failure:

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:
swfobject.js
, but there is alsosilverlight.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.<object …><embed …></object>
. I'm listing both theobject
andembed
as separate entries on the details list as they potentially can have different contents.