Commit b6bbb641 authored by Mike Dougherty's avatar Mike Dougherty Committed by Commit Bot

Cleanup plugin_placeholder.js

Remove exposed plugin API since all logic is now contained to a single
file and it runs immediately upon injection.

The unittests are now obsolete because no API is exposed. However, all
previous unittest scenarios are covered by the PluginPlaceholderTestCase
EarlGrey tests.

Bug: 802344
Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: I2f31af1fe9fa4f94f678064fe2a8cc316b837757
Reviewed-on: https://chromium-review.googlesource.com/899914
Commit-Queue: Mike Dougherty <michaeldo@chromium.org>
Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Cr-Commit-Position: refs/heads/master@{#534169}
parent 63612d32
...@@ -446,7 +446,6 @@ source_set("ios_web_web_state_js_unittests") { ...@@ -446,7 +446,6 @@ source_set("ios_web_web_state_js_unittests") {
"web_state/js/crw_js_post_request_loader_unittest.mm", "web_state/js/crw_js_post_request_loader_unittest.mm",
"web_state/js/crw_js_window_id_manager_unittest.mm", "web_state/js/crw_js_window_id_manager_unittest.mm",
"web_state/js/page_script_util_unittest.mm", "web_state/js/page_script_util_unittest.mm",
"web_state/js/plugin_placeholder_js_unittest.mm",
] ]
} }
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import <Foundation/Foundation.h>
#include "base/strings/sys_string_conversions.h"
#import "ios/web/public/test/web_test_with_web_state.h"
#include "testing/gtest/include/gtest/gtest.h"
#import "testing/gtest_mac.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace web {
// Test fixture to test plugin_placeholder.js.
typedef web::WebTestWithWebState PluginPlaceholderJsTest;
// Tests that __gCrWeb.plugin.updatePluginPlaceholders JavaScript API correctly
// find plugins which are candidates for covering with a placeholder.
// NOTE: Some of the plugins detected here may not actually be covered with a
// placeholder because __gCrWeb.plugin.addPluginPlaceholders also takes into
// account the physical size of the plugin.
TEST_F(PluginPlaceholderJsTest, UpdatePluginPlaceholders) {
struct TestData {
NSString* plugin_source;
BOOL expected_placeholder_installed;
} test_data[] = {
// Applet with fallback data should be untouched.
{@"<html><applet code='Some.class'><p>Fallback text.</p></applet>"
"</body></html>",
NO},
// Applet without fallback data should be covered.
{@"<html><applet code='Some.class'></applet></body></html>", YES},
// Object with flash embed fallback should be covered.
{@"<html><body>"
"<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'"
" codebase='http://download.macromedia.com/pub/shockwave/cabs/'"
"flash/swflash.cab#version=6,0,0,0'>"
" <param name='movie' value='some.swf'>"
" <embed src='some.swf' type='application/x-shockwave-flash'>"
"</object>"
"</body></html>",
YES},
// Object with undefined embed fallback should be untouched.
{@"<html><body>"
"<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'"
" codebase='http://download.macromedia.com/pub/shockwave/cabs/'"
"flash/swflash.cab#version=6,0,0,0'>"
" <param name='movie' value='some.swf'>"
" <embed src='some.swf'>"
"</object>"
"</body></html>",
NO},
// Object with text fallback should be untouched.
{@"<html><body>"
"<object type='application/x-shockwave-flash' data='some.sfw'>"
" <param name='movie' value='some.swf'>"
" <p>Fallback text.</p>"
"</object>"
"</body></html>",
NO},
// Object with no fallback should be covered.
{@"<html><body>"
"<object type='application/x-shockwave-flash' data='some.sfw'>"
" <param name='movie' value='some.swf'>"
"</object>"
"</body></html>",
YES},
// Object displaying an image should be untouched.
{@"<html><body>"
"<object data='foo.png' type='image/png'>"
"</object>"
"</body></html>",
NO},
};
for (size_t i = 0; i < arraysize(test_data); i++) {
TestData& data = test_data[i];
LoadHtml(data.plugin_source);
id result =
ExecuteJavaScript(@"__gCrWeb.plugin.updatePluginPlaceholders()");
EXPECT_NSEQ(@(data.expected_placeholder_installed), result)
<< " in test " << i << ": "
<< base::SysNSStringToUTF8(data.plugin_source);
}
}
} // namespace web
...@@ -5,16 +5,7 @@ ...@@ -5,16 +5,7 @@
// This file adheres to closure-compiler conventions in order to enable // This file adheres to closure-compiler conventions in order to enable
// compilation with ADVANCED_OPTIMIZATIONS. See http://goo.gl/FwOgy // compilation with ADVANCED_OPTIMIZATIONS. See http://goo.gl/FwOgy
// //
// Installs and runs the plugin placeholder function on the |__gCrWeb| object. // Inserts placeholders into the DOM on top of unsupported plugins.
goog.provide('__crWeb.plugin');
/**
* Namespace for this file. It depends on |__gCrWeb| having already been
* injected.
* TODO(crbug.com/802344): Cleanup this file.
*/
__gCrWeb['plugin'] = {};
/* Beginning of anonymous object. */ /* Beginning of anonymous object. */
(function() { (function() {
...@@ -26,7 +17,7 @@ __gCrWeb['plugin'] = {}; ...@@ -26,7 +17,7 @@ __gCrWeb['plugin'] = {};
* @return {boolean} Whether the node appears to be a plugin. * @return {boolean} Whether the node appears to be a plugin.
* @private * @private
*/ */
var objectNodeIsPlugin_ = function(node) { var objectNodeIsPlugin = function(node) {
return node.hasAttribute('classid') || return node.hasAttribute('classid') ||
(node.hasAttribute('type') && node.type.indexOf('image/') != 0); (node.hasAttribute('type') && node.type.indexOf('image/') != 0);
}; };
...@@ -39,7 +30,7 @@ __gCrWeb['plugin'] = {}; ...@@ -39,7 +30,7 @@ __gCrWeb['plugin'] = {};
* @return {boolean} Whether the node has any fallback content. * @return {boolean} Whether the node has any fallback content.
* @private * @private
*/ */
var nodeHasFallbackContent_ = function(node) { var nodeHasFallbackContent = function(node) {
if (node.textContent.trim().length > 0) { if (node.textContent.trim().length > 0) {
return true; return true;
} }
...@@ -63,7 +54,7 @@ __gCrWeb['plugin'] = {}; ...@@ -63,7 +54,7 @@ __gCrWeb['plugin'] = {};
* @return {HTMLElement} The embed fallback node, if one exists. * @return {HTMLElement} The embed fallback node, if one exists.
* @private * @private
*/ */
var getChildEmbedElement_ = function(node) { var getChildEmbedElement = function(node) {
var childrenCount = node.children.length; var childrenCount = node.children.length;
if (childrenCount == 0) { if (childrenCount == 0) {
return null; return null;
...@@ -83,7 +74,7 @@ __gCrWeb['plugin'] = {}; ...@@ -83,7 +74,7 @@ __gCrWeb['plugin'] = {};
* @return {boolean} Whether the node is known to be flash content. * @return {boolean} Whether the node is known to be flash content.
* @private * @private
*/ */
var embedNodeIsKnownFlashContent_ = function(node) { var embedNodeIsKnownFlashContent = function(node) {
return node.hasAttribute('type') && return node.hasAttribute('type') &&
(node.type.indexOf('application/x-shockwave-flash') == 0 || (node.type.indexOf('application/x-shockwave-flash') == 0 ||
node.type.indexOf('application/vnd.adobe.flash-movie') == 0); node.type.indexOf('application/vnd.adobe.flash-movie') == 0);
...@@ -96,13 +87,13 @@ __gCrWeb['plugin'] = {}; ...@@ -96,13 +87,13 @@ __gCrWeb['plugin'] = {};
* @return {boolean} Whether the node is supported. * @return {boolean} Whether the node is supported.
* @private * @private
*/ */
var pluginNodeIsSupported_ = function(node) { var pluginNodeIsSupported = function(node) {
if (!nodeHasFallbackContent_(node)) { if (!nodeHasFallbackContent(node)) {
return false; return false;
} }
var embedChildNode = getChildEmbedElement_(node); var embedChildNode = getChildEmbedElement(node);
if (embedChildNode && embedNodeIsKnownFlashContent_(embedChildNode)) { if (embedChildNode && embedNodeIsKnownFlashContent(embedChildNode)) {
return false; return false;
} }
...@@ -116,14 +107,13 @@ __gCrWeb['plugin'] = {}; ...@@ -116,14 +107,13 @@ __gCrWeb['plugin'] = {};
* @return {!Array<!HTMLElement>} A list of plugin elements. * @return {!Array<!HTMLElement>} A list of plugin elements.
* @private * @private
*/ */
var findPluginNodesWithoutFallback_ = function() { var findPluginNodesWithoutFallback = function() {
var i, pluginNodes = []; var i, pluginNodes = [];
var objects = document.getElementsByTagName('object'); var objects = document.getElementsByTagName('object');
var objectCount = objects.length; var objectCount = objects.length;
for (i = 0; i < objectCount; i++) { for (i = 0; i < objectCount; i++) {
var object = /** @type {!HTMLElement} */(objects[i]); var object = /** @type {!HTMLElement} */(objects[i]);
if (objectNodeIsPlugin_(object) && if (objectNodeIsPlugin(object) && !pluginNodeIsSupported(object)) {
!pluginNodeIsSupported_(object)) {
pluginNodes.push(object); pluginNodes.push(object);
} }
} }
...@@ -131,32 +121,17 @@ __gCrWeb['plugin'] = {}; ...@@ -131,32 +121,17 @@ __gCrWeb['plugin'] = {};
var appletsCount = applets.length; var appletsCount = applets.length;
for (i = 0; i < appletsCount; i++) { for (i = 0; i < appletsCount; i++) {
var applet = /** @type {!HTMLElement} */(applets[i]); var applet = /** @type {!HTMLElement} */(applets[i]);
if (!pluginNodeIsSupported_(applet)) { if (!pluginNodeIsSupported(applet)) {
pluginNodes.push(applet); pluginNodes.push(applet);
} }
} }
return pluginNodes; return pluginNodes;
}; };
/**
* Finds and stores any plugins that don't have placeholders.
* Returns true if any plugins without placeholders are found.
*/
__gCrWeb['plugin'].updatePluginPlaceholders = function() {
var plugins = findPluginNodesWithoutFallback_();
if (plugins.length > 0) {
// Store the list of plugins in a known place for the replacement script
// to use, then trigger it.
__gCrWeb['placeholderTargetPlugins'] = plugins;
return true;
}
return false;
};
/* Data-URL version of plugin_blocked_android.png. Served this way rather /* Data-URL version of plugin_blocked_android.png. Served this way rather
* than with an intercepted URL to avoid messing up https pages. * than with an intercepted URL to avoid messing up https pages.
*/ */
__gCrWeb['plugin'].imageData_ = var imageData =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAQAAABLCVATAAAD' + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAQAAABLCVATAAAD' +
'aklEQVR4Xn2Wz2tcVRTHP/e+O28mMxONJKlF4kIkP4luXFgQuuxCBaG41IWrLupOXLur+A' + 'aklEQVR4Xn2Wz2tcVRTHP/e+O28mMxONJKlF4kIkP4luXFgQuuxCBaG41IWrLupOXLur+A' +
'e4cmV3LiS6qujSLgq2CIKQUqS2YnWsRkzGSTIz7zyHw+EdchnkcOd+7+OeT84578tMwmet' + 'e4cmV3LiS6qujSLgq2CIKQUqS2YnWsRkzGSTIz7zyHw+EdchnkcOd+7+OeT84578tMwmet' +
...@@ -180,14 +155,14 @@ __gCrWeb['plugin'] = {}; ...@@ -180,14 +155,14 @@ __gCrWeb['plugin'] = {};
/** /**
* Returns the first <embed> child of the given node, if any. * Returns the first <embed> child of the given node, if any.
* @param {Node} node The node to check. * @param {Node} node The node to check.
* @return {Node} The first <embed> child, or null. * @return {HTMLElement} The first <embed> child, or null.
* @private * @private
*/ */
__gCrWeb['plugin'].getEmbedChild_ = function(node) { var getEmbedChild = function(node) {
if (node.hasChildNodes()) { if (node.hasChildNodes()) {
for (var i = 0; i < node.childNodes.length; i++) { for (var i = 0; i < node.childNodes.length; i++) {
if (node.childNodes[i].nodeName === 'EMBED') { if (node.childNodes[i].nodeName === 'EMBED') {
return node.childNodes[i]; return /** @type {HTMLElement} */ (node.childNodes[i]);
} }
} }
} }
...@@ -203,12 +178,12 @@ __gCrWeb['plugin'] = {}; ...@@ -203,12 +178,12 @@ __gCrWeb['plugin'] = {};
* @return {Object} The size (width and height) for the plugin element. * @return {Object} The size (width and height) for the plugin element.
* @private * @private
*/ */
__gCrWeb['plugin'].getPluginSize_ = function(plugin) { var getPluginSize = function(plugin) {
var style; var style;
// For the common pattern of an IE-specific <object> wrapping an // For the common pattern of an IE-specific <object> wrapping an
// all-other-browsers <embed>, the object doesn't have real style info // all-other-browsers <embed>, the object doesn't have real style info
// (most notably size), so this uses the embed in that case. // (most notably size), so this uses the embed in that case.
var embedChild = __gCrWeb['plugin'].getEmbedChild_(plugin); var embedChild = getEmbedChild(plugin);
if (embedChild) { if (embedChild) {
style = window.getComputedStyle(embedChild); style = window.getComputedStyle(embedChild);
} else { } else {
...@@ -242,10 +217,10 @@ __gCrWeb['plugin'] = {}; ...@@ -242,10 +217,10 @@ __gCrWeb['plugin'] = {};
* @return {boolean} Whether the node is significant. * @return {boolean} Whether the node is significant.
* @private * @private
*/ */
__gCrWeb['plugin'].isSignificantPlugin_ = function(plugin) { var isSignificantPlugin = function(plugin) {
var windowWidth = window.innerWidth; var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight; var windowHeight = window.innerHeight;
var pluginSize = __gCrWeb['plugin'].getPluginSize_(plugin); var pluginSize = getPluginSize(plugin);
var pluginWidth = parseFloat(pluginSize.width); var pluginWidth = parseFloat(pluginSize.width);
var pluginHeight = parseFloat(pluginSize.height); var pluginHeight = parseFloat(pluginSize.height);
// A plugin must be at least |significantFraction| of one dimension of the // A plugin must be at least |significantFraction| of one dimension of the
...@@ -263,16 +238,18 @@ __gCrWeb['plugin'] = {}; ...@@ -263,16 +238,18 @@ __gCrWeb['plugin'] = {};
* Walks the list of detected plugin elements, adding a placeholder to any * Walks the list of detected plugin elements, adding a placeholder to any
* that are "significant" (see above). * that are "significant" (see above).
* @param {string} message The message to show in the placeholder. * @param {string} message The message to show in the placeholder.
* @param {!Array<!HTMLElement>} plugins A list of plugin elements.
* @private
*/ */
__gCrWeb['plugin'].addPluginPlaceholders = function(message) { var addPluginPlaceholders = function(message, plugins) {
var i, plugins = __gCrWeb['placeholderTargetPlugins']; var i;
for (i = 0; i < plugins.length; i++) { for (i = 0; i < plugins.length; i++) {
var plugin = plugins[i]; var plugin = plugins[i];
if (!__gCrWeb['plugin'].isSignificantPlugin_(plugin)) { if (!isSignificantPlugin(plugin)) {
continue; continue;
} }
var pluginSize = __gCrWeb['plugin'].getPluginSize_(plugin); var pluginSize = getPluginSize(plugin);
var widthStyle = pluginSize.width + 'px'; var widthStyle = pluginSize.width + 'px';
var heightStyle = pluginSize.height + 'px'; var heightStyle = pluginSize.height + 'px';
...@@ -285,7 +262,7 @@ __gCrWeb['plugin'] = {}; ...@@ -285,7 +262,7 @@ __gCrWeb['plugin'] = {};
// avoid being affected by container alignment. // avoid being affected by container alignment.
var placeholder = document.createElement('div'); var placeholder = document.createElement('div');
placeholder.style.width = widthStyle; placeholder.style.width = widthStyle;
if (__gCrWeb['plugin'].getEmbedChild_(plugin)) { if (getEmbedChild(plugin)) {
placeholder.style.height = '0'; placeholder.style.height = '0';
} else { } else {
placeholder.style.height = heightStyle; placeholder.style.height = heightStyle;
...@@ -314,7 +291,7 @@ __gCrWeb['plugin'] = {}; ...@@ -314,7 +291,7 @@ __gCrWeb['plugin'] = {};
pluginImg.style.marginTop = '-' + halfSize + 'px'; pluginImg.style.marginTop = '-' + halfSize + 'px';
pluginImg.style.left = '50%'; pluginImg.style.left = '50%';
pluginImg.style.marginLeft = '-' + halfSize + 'px'; pluginImg.style.marginLeft = '-' + halfSize + 'px';
pluginImg.src = __gCrWeb['plugin'].imageData_; pluginImg.src = imageData;
placeholderBox.appendChild(pluginImg); placeholderBox.appendChild(pluginImg);
// And below that, the message. // And below that, the message.
...@@ -335,10 +312,11 @@ __gCrWeb['plugin'] = {}; ...@@ -335,10 +312,11 @@ __gCrWeb['plugin'] = {};
}; };
// Add placeholders for plugin content. // Add placeholders for plugin content.
if (__gCrWeb['plugin'].updatePluginPlaceholders()) { var plugins = findPluginNodesWithoutFallback();
if (plugins.length > 0) {
// web::GetDocumentEndScriptForAllFrames replaces // web::GetDocumentEndScriptForAllFrames replaces
// $(PLUGIN_NOT_SUPPORTED_TEXT) with approproate string upon injection. // $(PLUGIN_NOT_SUPPORTED_TEXT) with approproate string upon injection.
__gCrWeb['plugin'].addPluginPlaceholders('$(PLUGIN_NOT_SUPPORTED_TEXT)'); addPluginPlaceholders('$(PLUGIN_NOT_SUPPORTED_TEXT)', plugins);
} }
}()); // End of anonymous object }()); // End of anonymous object
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment