Commit 0c41b90c authored by rdevlin.cronin's avatar rdevlin.cronin Committed by Commit Bot

Revert of Move ObjectContentType entirely to HTMLPlugInElement (patchset #2...

Revert of Move ObjectContentType entirely to HTMLPlugInElement (patchset #2 id:20001 of https://codereview.chromium.org/2927703003/ )

Reason for revert:
Looks like schenney's unavailable at the moment; speculatively reverting for layout test virtual/new-remote-playback-pipeline/media/controls/controls-cast-overlay-slow-fade.html failures (e.g. https://build.chromium.org/p/chromium.linux/builders/Linux%20Tests/builds/57955)

Original issue's description:
> Move ObjectContentType entirely to HTMLPlugInElement
>
> There's no need to go to LocalFrameClientImpl to determine how to load
> a plugin element, that was a purely pre-blink necessity.
>
> Simplify a bunch of logic around HTMLPlugInElement to assume that url_
> and service_type_ are always set and correct by the time the
> ObjectContentType is being determined.
>
> BUG=
>
> Review-Url: https://codereview.chromium.org/2927703003
> Cr-Commit-Position: refs/heads/master@{#478683}
> Committed: https://chromium.googlesource.com/chromium/src/+/2718186cc8ac74b38b9a7304764642f05c76bb81

TBR=schenney@chromium.org,japhet@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=

Review-Url: https://codereview.chromium.org/2933213002
Cr-Commit-Position: refs/heads/master@{#478781}
parent 3043b941
......@@ -223,6 +223,11 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
virtual WebRemotePlaybackClient* CreateWebRemotePlaybackClient(
HTMLMediaElement&) = 0;
virtual ObjectContentType GetObjectContentType(
const KURL&,
const String& mime_type,
bool should_prefer_plug_ins_for_images) = 0;
virtual void DidCreateNewDocument() = 0;
virtual void DispatchDidClearWindowObjectInMainWorld() = 0;
virtual void DocumentElementAvailable() = 0;
......
......@@ -175,7 +175,7 @@ void HTMLEmbedElement::UpdatePluginInternal() {
service_type_ = "text/html";
}
RequestObject(param_names, param_values);
RequestObject(url_, service_type_, param_names, param_values);
}
bool HTMLEmbedElement::LayoutObjectIsNeeded(const ComputedStyle& style) {
......
......@@ -148,8 +148,11 @@ static void MapDataParamToSrc(Vector<String>* param_names,
// TODO(schenney): crbug.com/572908 This function should not deal with url or
// serviceType!
void HTMLObjectElement::ParametersForPlugin(Vector<String>& param_names,
Vector<String>& param_values) {
Vector<String>& param_values,
String& url,
String& service_type) {
HashSet<StringImpl*, CaseFoldingHash> unique_param_names;
String url_parameter;
// Scan the PARAM children and store their name/value pairs.
// Get the URL and type from the params if we don't already have them.
......@@ -165,25 +168,35 @@ void HTMLObjectElement::ParametersForPlugin(Vector<String>& param_names,
// TODO(schenney): crbug.com/572908 url adjustment does not belong in this
// function.
// HTML5 says that an object resource's URL is specified by the object's
// data attribute, not by a param element. However, for compatibility, allow
// the resource's URL to be given by a param named "src", "movie", "code" or
// "url" if we know that resource points to a plugin.
if (url_.IsEmpty() && (DeprecatedEqualIgnoringCase(name, "src") ||
DeprecatedEqualIgnoringCase(name, "movie") ||
DeprecatedEqualIgnoringCase(name, "code") ||
DeprecatedEqualIgnoringCase(name, "url"))) {
url_ = StripLeadingAndTrailingHTMLSpaces(p->Value());
}
if (url.IsEmpty() && url_parameter.IsEmpty() &&
(DeprecatedEqualIgnoringCase(name, "src") ||
DeprecatedEqualIgnoringCase(name, "movie") ||
DeprecatedEqualIgnoringCase(name, "code") ||
DeprecatedEqualIgnoringCase(name, "url")))
url_parameter = StripLeadingAndTrailingHTMLSpaces(p->Value());
// TODO(schenney): crbug.com/572908 serviceType calculation does not belong
// in this function.
if (service_type_.IsEmpty() && DeprecatedEqualIgnoringCase(name, "type")) {
size_t pos = p->Value().Find(";");
if (service_type.IsEmpty() && DeprecatedEqualIgnoringCase(name, "type")) {
service_type = p->Value();
size_t pos = service_type.Find(";");
if (pos != kNotFound)
service_type_ = p->Value().GetString().Left(pos);
service_type = service_type.Left(pos);
}
}
// When OBJECT is used for an applet via Sun's Java plugin, the CODEBASE
// attribute in the tag points to the Java plugin itself (an ActiveX
// component) while the actual applet CODEBASE is in a PARAM tag. See
// <http://java.sun.com/products/plugin/1.2/docs/tags.html>. This means we
// have to explicitly suppress the tag's CODEBASE attribute if there is none
// in a PARAM, else our Java plugin will misinterpret it. [4004531]
String codebase;
if (MIMETypeRegistry::IsJavaAppletMIMEType(service_type)) {
codebase = "codebase";
unique_param_names.insert(
codebase.Impl()); // pretend we found it in a PARAM already
}
// Turn the attributes of the <object> element into arrays, but don't override
// <param> values.
AttributeCollection attributes = this->Attributes();
......@@ -196,6 +209,17 @@ void HTMLObjectElement::ParametersForPlugin(Vector<String>& param_names,
}
MapDataParamToSrc(&param_names, &param_values);
// HTML5 says that an object resource's URL is specified by the object's data
// attribute, not by a param element. However, for compatibility, allow the
// resource's URL to be given by a param named "src", "movie", "code" or "url"
// if we know that resource points to a plugin.
if (url.IsEmpty() && !url_parameter.IsEmpty()) {
KURL completed_url = GetDocument().CompleteURL(url_parameter);
bool use_fallback;
if (ShouldUsePlugin(completed_url, service_type, false, use_fallback))
url = url_parameter;
}
}
bool HTMLObjectElement::HasFallbackContent() const {
......@@ -268,14 +292,17 @@ void HTMLObjectElement::UpdatePluginInternal() {
return;
}
String url = this->Url();
String service_type = service_type_;
// TODO(schenney): crbug.com/572908 These should be joined into a
// PluginParameters class.
Vector<String> param_names;
Vector<String> param_values;
ParametersForPlugin(param_names, param_values);
ParametersForPlugin(param_names, param_values, url, service_type);
// Note: url is modified above by parametersForPlugin.
if (!AllowedToLoadFrameURL(url_)) {
if (!AllowedToLoadFrameURL(url)) {
DispatchErrorEvent();
return;
}
......@@ -290,12 +317,13 @@ void HTMLObjectElement::UpdatePluginInternal() {
GetDocument().GetFrame()->Loader().Client()->OverrideFlashEmbedWithHTML(
GetDocument().CompleteURL(url_));
if (!overriden_url.IsEmpty()) {
url_ = overriden_url.GetString();
service_type_ = "text/html";
url = url_ = overriden_url.GetString();
service_type = service_type_ = "text/html";
}
if (!HasValidClassId() || !RequestObject(param_names, param_values)) {
if (!url_.IsEmpty())
if (!HasValidClassId() ||
!RequestObject(url, service_type, param_names, param_values)) {
if (!url.IsEmpty())
DispatchErrorEvent();
if (HasFallbackContent())
RenderFallbackContent();
......
......@@ -110,7 +110,9 @@ class CORE_EXPORT HTMLObjectElement final : public HTMLPlugInElement,
// FIXME: This function should not deal with url or serviceType
// so that we can better share code between <object> and <embed>.
void ParametersForPlugin(Vector<String>& param_names,
Vector<String>& param_values);
Vector<String>& param_values,
String& url,
String& service_type);
bool HasValidClassId() const;
......
......@@ -118,22 +118,23 @@ void HTMLPlugInElement::SetFocused(bool focused, WebFocusType focus_type) {
}
bool HTMLPlugInElement::RequestObjectInternal(
const String& url,
const String& mime_type,
const Vector<String>& param_names,
const Vector<String>& param_values) {
if (url_.IsEmpty() && service_type_.IsEmpty())
if (url.IsEmpty() && mime_type.IsEmpty())
return false;
if (ProtocolIsJavaScript(url_))
if (ProtocolIsJavaScript(url))
return false;
KURL completed_url =
url_.IsEmpty() ? KURL() : GetDocument().CompleteURL(url_);
if (!AllowedToLoadObject(completed_url, service_type_))
KURL completed_url = url.IsEmpty() ? KURL() : GetDocument().CompleteURL(url);
if (!AllowedToLoadObject(completed_url, mime_type))
return false;
ObjectContentType object_type = GetObjectContentType();
if (object_type == ObjectContentType::kFrame ||
object_type == ObjectContentType::kImage) {
bool use_fallback;
if (!ShouldUsePlugin(completed_url, mime_type, HasFallbackContent(),
use_fallback)) {
// If the plugin element already contains a subframe,
// loadOrRedirectSubframe will re-use it. Otherwise, it will create a
// new frame and set it as the LayoutEmbeddedContent's EmbeddedContentView,
......@@ -141,11 +142,7 @@ bool HTMLPlugInElement::RequestObjectInternal(
return LoadOrRedirectSubframe(completed_url, GetNameAttribute(), true);
}
// If an object's content can't be handled and it has no fallback, let
// it be handled as a plugin to show the broken plugin icon.
bool use_fallback =
object_type == ObjectContentType::kNone && HasFallbackContent();
return LoadPlugin(completed_url, service_type_, param_names, param_values,
return LoadPlugin(completed_url, mime_type, param_names, param_values,
use_fallback, true);
}
......@@ -197,7 +194,7 @@ void HTMLPlugInElement::AttachLayoutTree(const AttachContext& context) {
image_loader_->UpdateFromElement();
} else if (NeedsPluginUpdate() && !GetLayoutEmbeddedItem().IsNull() &&
!GetLayoutEmbeddedItem().ShowsUnavailablePluginIndicator() &&
GetObjectContentType() != ObjectContentType::kPlugin &&
!WouldLoadAsNetscapePlugin(url_, service_type_) &&
!is_delaying_load_event_) {
is_delaying_load_event_ = true;
GetDocument().IncrementLoadEventDelayCount();
......@@ -472,46 +469,17 @@ bool HTMLPlugInElement::LayoutObjectIsFocusable() const {
return plugin_is_available_;
}
HTMLPlugInElement::ObjectContentType HTMLPlugInElement::GetObjectContentType() {
String mime_type = service_type_;
KURL url = GetDocument().CompleteURL(url_);
if (mime_type.IsEmpty()) {
// Try to guess the MIME type based off the extension.
String filename = url.LastPathComponent();
int extension_pos = filename.ReverseFind('.');
if (extension_pos >= 0) {
String extension = filename.Substring(extension_pos + 1);
mime_type = MIMETypeRegistry::GetWellKnownMIMETypeForExtension(extension);
}
if (mime_type.IsEmpty())
return ObjectContentType::kFrame;
}
// If Chrome is started with the --disable-plugins switch, pluginData is 0.
PluginData* plugin_data = GetDocument().GetFrame()->GetPluginData();
bool plugin_supports_mime_type =
plugin_data && plugin_data->SupportsMimeType(mime_type);
if (MIMETypeRegistry::IsSupportedImageMIMEType(mime_type)) {
return should_prefer_plug_ins_for_images_ && plugin_supports_mime_type
? ObjectContentType::kPlugin
: ObjectContentType::kImage;
}
if (plugin_supports_mime_type)
return ObjectContentType::kPlugin;
if (MIMETypeRegistry::IsSupportedNonImageMIMEType(mime_type))
return ObjectContentType::kFrame;
return ObjectContentType::kNone;
}
bool HTMLPlugInElement::IsImageType() {
if (service_type_.IsEmpty() && ProtocolIs(url_, "data"))
service_type_ = MimeTypeFromDataURL(url_);
if (GetDocument().GetFrame())
return GetObjectContentType() == ObjectContentType::kImage;
if (LocalFrame* frame = GetDocument().GetFrame()) {
KURL completed_url = GetDocument().CompleteURL(url_);
return frame->Loader().Client()->GetObjectContentType(
completed_url, service_type_, ShouldPreferPlugInsForImages()) ==
kObjectContentImage;
}
return Image::SupportsType(service_type_);
}
......@@ -532,9 +500,25 @@ bool HTMLPlugInElement::AllowedToLoadFrameURL(const String& url) {
ContentFrame()->GetSecurityContext()->GetSecurityOrigin()));
}
bool HTMLPlugInElement::RequestObject(const Vector<String>& param_names,
// We don't use m_url, or m_serviceType as they may not be the final values
// that <object> uses depending on <param> values.
bool HTMLPlugInElement::WouldLoadAsNetscapePlugin(const String& url,
const String& service_type) {
DCHECK(GetDocument().GetFrame());
KURL completed_url;
if (!url.IsEmpty())
completed_url = GetDocument().CompleteURL(url);
return GetDocument().GetFrame()->Loader().Client()->GetObjectContentType(
completed_url, service_type, ShouldPreferPlugInsForImages()) ==
kObjectContentNetscapePlugin;
}
bool HTMLPlugInElement::RequestObject(const String& url,
const String& mime_type,
const Vector<String>& param_names,
const Vector<String>& param_values) {
bool result = RequestObjectInternal(param_names, param_values);
bool result =
RequestObjectInternal(url, mime_type, param_names, param_values);
DEFINE_STATIC_LOCAL(
EnumerationHistogram, result_histogram,
......@@ -609,6 +593,20 @@ bool HTMLPlugInElement::LoadPlugin(const KURL& url,
return true;
}
bool HTMLPlugInElement::ShouldUsePlugin(const KURL& url,
const String& mime_type,
bool has_fallback,
bool& use_fallback) {
ObjectContentType object_type =
GetDocument().GetFrame()->Loader().Client()->GetObjectContentType(
url, mime_type, ShouldPreferPlugInsForImages());
// If an object's content can't be handled and it has no fallback, let
// it be handled as a plugin to show the broken plugin icon.
use_fallback = object_type == kObjectContentNone && has_fallback;
return object_type == kObjectContentNone ||
object_type == kObjectContentNetscapePlugin;
}
void HTMLPlugInElement::DispatchErrorEvent() {
if (GetDocument().IsPluginDocument() && GetDocument().LocalOwner())
GetDocument().LocalOwner()->DispatchEvent(
......
......@@ -106,10 +106,19 @@ class CORE_EXPORT HTMLPlugInElement
virtual LayoutEmbeddedContent* LayoutEmbeddedContentForJSBindings() const;
bool IsImageType();
bool ShouldPreferPlugInsForImages() const {
return should_prefer_plug_ins_for_images_;
}
LayoutEmbeddedItem GetLayoutEmbeddedItem() const;
bool AllowedToLoadFrameURL(const String& url);
bool RequestObject(const Vector<String>& param_names,
bool RequestObject(const String& url,
const String& mime_type,
const Vector<String>& param_names,
const Vector<String>& param_values);
bool ShouldUsePlugin(const KURL&,
const String& mime_type,
bool has_fallback,
bool& use_fallback);
void DispatchErrorEvent();
bool IsErrorplaceholder();
......@@ -164,18 +173,13 @@ class CORE_EXPORT HTMLPlugInElement
bool AllowedToLoadPlugin(const KURL&, const String& mime_type);
// Perform checks based on the URL and MIME-type of the object to load.
bool AllowedToLoadObject(const KURL&, const String& mime_type);
enum class ObjectContentType {
kNone,
kImage,
kFrame,
kPlugin,
};
ObjectContentType GetObjectContentType();
bool WouldLoadAsNetscapePlugin(const String& url, const String& service_type);
void SetPersistedPlugin(PluginView*);
bool RequestObjectInternal(const Vector<String>& param_names,
bool RequestObjectInternal(const String& url,
const String& mime_type,
const Vector<String>& param_names,
const Vector<String>& param_values);
v8::Global<v8::Object> plugin_wrapper_;
......
......@@ -339,6 +339,12 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
WebRemotePlaybackClient* CreateWebRemotePlaybackClient(
HTMLMediaElement&) override;
ObjectContentType GetObjectContentType(const KURL&,
const String&,
bool) override {
return ObjectContentType();
}
void DidCreateNewDocument() override {}
void DispatchDidClearWindowObjectInMainWorld() override {}
void DocumentElementAvailable() override {}
......
......@@ -51,6 +51,13 @@ enum NavigationType {
kNavigationTypeOther
};
enum ObjectContentType {
kObjectContentNone,
kObjectContentImage,
kObjectContentFrame,
kObjectContentNetscapePlugin,
};
enum ShouldSendReferrer { kMaybeSendReferrer, kNeverSendReferrer };
enum ShouldSetOpener { kMaybeSetOpener, kNeverSetOpener };
......
......@@ -81,6 +81,7 @@
#include "platform/feature_policy/FeaturePolicy.h"
#include "platform/loader/fetch/ResourceFetcher.h"
#include "platform/network/HTTPParsers.h"
#include "platform/network/mime/MIMETypeRegistry.h"
#include "platform/plugins/PluginData.h"
#include "platform/wtf/PtrUtil.h"
#include "platform/wtf/StringExtras.h"
......@@ -813,6 +814,47 @@ WebRemotePlaybackClient* LocalFrameClientImpl::CreateWebRemotePlaybackClient(
return HTMLMediaElementRemotePlayback::remote(html_media_element);
}
ObjectContentType LocalFrameClientImpl::GetObjectContentType(
const KURL& url,
const String& explicit_mime_type,
bool should_prefer_plug_ins_for_images) {
// This code is based on Apple's implementation from
// WebCoreSupport/WebFrameBridge.mm.
String mime_type = explicit_mime_type;
if (mime_type.IsEmpty()) {
// Try to guess the MIME type based off the extension.
String filename = url.LastPathComponent();
int extension_pos = filename.ReverseFind('.');
if (extension_pos >= 0) {
String extension = filename.Substring(extension_pos + 1);
mime_type = MIMETypeRegistry::GetWellKnownMIMETypeForExtension(extension);
}
if (mime_type.IsEmpty())
return kObjectContentFrame;
}
// If Chrome is started with the --disable-plugins switch, pluginData is 0.
PluginData* plugin_data = web_frame_->GetFrame()->GetPluginData();
bool plug_in_supports_mime_type =
plugin_data && plugin_data->SupportsMimeType(mime_type);
if (MIMETypeRegistry::IsSupportedImageMIMEType(mime_type)) {
return should_prefer_plug_ins_for_images && plug_in_supports_mime_type
? kObjectContentNetscapePlugin
: kObjectContentImage;
}
if (plug_in_supports_mime_type)
return kObjectContentNetscapePlugin;
if (MIMETypeRegistry::IsSupportedNonImageMIMEType(mime_type))
return kObjectContentFrame;
return kObjectContentNone;
}
WebCookieJar* LocalFrameClientImpl::CookieJar() const {
if (!web_frame_->Client())
return 0;
......
......@@ -163,6 +163,10 @@ class LocalFrameClientImpl final : public LocalFrameClient {
WebMediaPlayerClient*) override;
WebRemotePlaybackClient* CreateWebRemotePlaybackClient(
HTMLMediaElement&) override;
ObjectContentType GetObjectContentType(
const KURL&,
const WTF::String& mime_type,
bool should_prefer_plug_ins_for_images) override;
void DidChangeScrollOffset() override;
void DidUpdateCurrentHistoryItem() override;
......
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