bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback, bool requireLayoutObject)
{
    LocalFrame* frame = document().frame();

    if (!frame->loader().allowPlugins(AboutToInstantiatePlugin))
        return false;

    LayoutEmbeddedObject* layoutObject = layoutEmbeddedObject();
    // FIXME: This code should not depend on layoutObject!
    if ((!layoutObject && requireLayoutObject) || useFallback)
        return false;

    WTF_LOG(Plugins, "%p Plugin URL: %s", this, m_url.utf8().data());
    WTF_LOG(Plugins, "   Loaded URL: %s", url.string().utf8().data());
    m_loadedUrl = url;

    OwnPtrWillBeRawPtr<PluginPlaceholder> placeholder = nullptr;
    RefPtrWillBeRawPtr<Widget> widget = m_persistedPluginWidget;
    if (!widget) {
        bool loadManually = document().isPluginDocument() && !document().containsPlugins();
        placeholder = frame->loader().client()->createPluginPlaceholder(document(), url, paramNames, paramValues, mimeType, loadManually);
        if (!placeholder) {
            FrameLoaderClient::DetachedPluginPolicy policy = requireLayoutObject ? FrameLoaderClient::FailOnDetachedPlugin : FrameLoaderClient::AllowDetachedPlugin;
            widget = frame->loader().client()->createPlugin(this, url, paramNames, paramValues, mimeType, loadManually, policy);
        }
    }

    if (!placeholder && !widget) {
        if (layoutObject && !layoutObject->showsUnavailablePluginIndicator())
            layoutObject->setPluginUnavailabilityReason(LayoutEmbeddedObject::PluginMissing);
        setPlaceholder(nullptr);
        return false;
    }

    if (placeholder) {
        setPlaceholder(placeholder.release());
        return true;
    }

    if (layoutObject) {
        setWidget(widget);
        setPersistedPluginWidget(nullptr);
    } else {
        setPersistedPluginWidget(widget.get());
    }
    setPlaceholder(nullptr);
    document().setContainsPlugins();
    scheduleSVGFilterLayerUpdateHack();
    // Make sure any input event handlers introduced by the plugin are taken into account.
    if (Page* page = document().frame()->page()) {
        if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
            scrollingCoordinator->notifyLayoutUpdated();
    }
    return true;
}
bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback, bool requireLayoutObject)
{
    if (!allowedToLoadPlugin(url, mimeType))
        return false;

    LocalFrame* frame = document().frame();
    if (!frame->loader().allowPlugins(AboutToInstantiatePlugin))
        return false;

    LayoutEmbeddedObject* layoutObject = layoutEmbeddedObject();
    // FIXME: This code should not depend on layoutObject!
    if ((!layoutObject && requireLayoutObject) || useFallback)
        return false;

    WTF_LOG(Plugins, "%p Plugin URL: %s", this, m_url.utf8().data());
    WTF_LOG(Plugins, "   Loaded URL: %s", url.string().utf8().data());
    m_loadedUrl = url;

    if (m_persistedPluginWidget) {
        setWidget(m_persistedPluginWidget.release());
    } else {
        bool loadManually = document().isPluginDocument() && !document().containsPlugins();
        FrameLoaderClient::DetachedPluginPolicy policy = requireLayoutObject ? FrameLoaderClient::FailOnDetachedPlugin : FrameLoaderClient::AllowDetachedPlugin;
        RefPtrWillBeRawPtr<Widget> widget = frame->loader().client()->createPlugin(this, url, paramNames, paramValues, mimeType, loadManually, policy);
        if (!widget) {
            if (layoutObject && !layoutObject->showsUnavailablePluginIndicator())
                layoutObject->setPluginUnavailabilityReason(LayoutEmbeddedObject::PluginMissing);
            return false;
        }

        if (layoutObject)
            setWidget(widget);
        else
            setPersistedPluginWidget(widget.get());
    }

    document().setContainsPlugins();
    // TODO(esprehn): WebPluginContainerImpl::setWebLayer also schedules a compositing update, do we need both?
    setNeedsCompositingUpdate();
    // Make sure any input event handlers introduced by the plugin are taken into account.
    if (Page* page = document().frame()->page()) {
        if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
            scrollingCoordinator->notifyGeometryChanged();
    }
    return true;
}
void HTMLAppletElement::updateWidgetInternal()
{
    setNeedsWidgetUpdate(false);
    // FIXME: This should ASSERT isFinishedParsingChildren() instead.
    if (!isFinishedParsingChildren())
        return;

    LayoutEmbeddedObject* layoutObject = layoutEmbeddedObject();

    LocalFrame* frame = document().frame();
    ASSERT(frame);

    Vector<String> paramNames;
    Vector<String> paramValues;

    const AtomicString& codeBase = getAttribute(codebaseAttr);
    if (!codeBase.isNull()) {
        KURL codeBaseURL = document().completeURL(codeBase);
        paramNames.append("codeBase");
        paramValues.append(codeBase.string());
    }

    const AtomicString& archive = getAttribute(archiveAttr);
    if (!archive.isNull()) {
        paramNames.append("archive");
        paramValues.append(archive.string());
    }

    const AtomicString& code = getAttribute(codeAttr);
    paramNames.append("code");
    paramValues.append(code.string());

    // If the 'codebase' attribute is set, it serves as a relative root for the file that the Java
    // plugin will load. If the 'code' attribute is set, and the 'archive' is not set, then we need
    // to check the url generated by resolving 'code' against 'codebase'. If the 'archive'
    // attribute is set, then 'code' points to a class inside the archive, so we need to check the
    // url generated by resolving 'archive' against 'codebase'.
    KURL urlToCheck;
    KURL rootURL;
    if (!codeBase.isNull())
        rootURL = document().completeURL(codeBase);
    if (rootURL.isNull() || !rootURL.isValid())
        rootURL = document().url();

    if (!archive.isNull())
        urlToCheck = KURL(rootURL, archive);
    else if (!code.isNull())
        urlToCheck = KURL(rootURL, code);
    if (!canEmbedURL(urlToCheck))
        return;

    const AtomicString& name = document().isHTMLDocument() ? getNameAttribute() : getIdAttribute();
    if (!name.isNull()) {
        paramNames.append("name");
        paramValues.append(name.string());
    }

    paramNames.append("baseURL");
    KURL baseURL = document().baseURL();
    paramValues.append(baseURL.string());

    const AtomicString& mayScript = getAttribute(mayscriptAttr);
    if (!mayScript.isNull()) {
        paramNames.append("mayScript");
        paramValues.append(mayScript.string());
    }

    for (HTMLParamElement* param = Traversal<HTMLParamElement>::firstChild(*this); param; param = Traversal<HTMLParamElement>::nextSibling(*param)) {
        if (param->name().isEmpty())
            continue;

        paramNames.append(param->name());
        paramValues.append(param->value());
    }

    OwnPtrWillBeRawPtr<PluginPlaceholder> placeholder = nullptr;
    RefPtrWillBeRawPtr<Widget> widget = nullptr;
    if (frame->loader().allowPlugins(AboutToInstantiatePlugin)) {
        placeholder = frame->loader().client()->createPluginPlaceholder(document(), KURL(), paramNames, paramValues, m_serviceType, false);
        if (!placeholder)
            widget = frame->loader().client()->createJavaAppletWidget(this, baseURL, paramNames, paramValues);
    }

    if (!placeholder && !widget) {
        if (!layoutObject->showsUnavailablePluginIndicator())
            layoutObject->setPluginUnavailabilityReason(LayoutEmbeddedObject::PluginMissing);
        setPlaceholder(nullptr);
    } else if (placeholder) {
        setPlaceholder(placeholder.release());
    } else if (widget) {
        document().setContainsPlugins();
        setWidget(widget);
        setPlaceholder(nullptr);
    }
}