Changeset 149586 in webkit


Ignore:
Timestamp:
May 6, 2013 1:24:58 AM (11 years ago)
Author:
Antoine Quint
Message:

Manage the presentation of the snapshotted plug-in using JavaScript
https://bugs.webkit.org/show_bug.cgi?id=115548

Reviewed by Dean Jackson.

Source/WebCore:

  • Resources/plugIns.js:

(createOverlay):
Implement the createOverlay(shadowRoot, titleText, subtitleText) method
that is called from WebCore (HTMLPlugInImageElement::didAddUserAgentShadowRoot)
to allow the injected script to customize the shadow root for a snapshotted
plug-in. This is a default implementation, clients are expected to customize
this by providing their own JS file with enhanced behavior.

  • css/CSSDefaultStyleSheets.cpp:

(WebCore::CSSDefaultStyleSheets::ensureDefaultStyleSheetsForElement):
Since we no longer have a default shadow tree generated in C++, it makes little
sense for clients to extend the default snapshotted plug-in stylesheet, so we
only insert it if no custom one is provided by the chrome client.

  • css/plugIns.css:

Better styling of the default snapshotted plug-in overlay look by using CSS
flex boxes. Also using more explicit selector as an optimization.

  • dom/Document.cpp:

(WebCore::Document::ensurePlugInsInjectedScript):
Expose a new method to allow HTMLPlugInImageElement instances to ensure that
the JavaScript code required to customize the snapshotted plug-in's shadow root
is indeed injected in the current document. The actual injection would only
happen once per document so all snapshotted plug-ins share the same scripting
context.

  • dom/Document.h:

Expose the new ensurePlugInsInjectedScript method and the m_hasInjectedPlugInsScript
property used to ensure injection happens only once per document.

  • html/HTMLPlugInImageElement.cpp:

(WebCore::titleText):
(WebCore::subtitleText):
Store the localized strings for each mime-type in a static hash map as it can be
costly to retrieve them each time from the client. It is expected the chrome client
will want to provide localized strings taking into account the snapshotted plug-in's
mime-type, so we're adding this as a parameter.
(WebCore::HTMLPlugInImageElement::checkSnapshotStatus):
Dispatch a "resize" event to the shadow root to notify the injected script that the
snapshotted plug-in's metrics have changed and to allow the overlay to update itself
as a result.
(WebCore::HTMLPlugInImageElement::didAddUserAgentShadowRoot):
Remove all the DOM generation code in favor of an approach where we create a shared
DOM scripting world in which we inject JavaScript code that will perform the same
task but will additionally be provided by the client in order to provide a completely
custom overlay for the snapshotted plug-in. The sole contract is for the JavaScript
to implement a createOverlay(shadowRoot, titleText, subtitleText) method.
(WebCore::HTMLPlugInImageElement::partOfSnapshotOverlay):
Renamed method to be generic to the overlay as opposed to text labels and use the
element with CSS class name "snapshot-overlay" as the comparison node.

  • html/HTMLPlugInImageElement.h:

(HTMLPlugInImageElement):
Removing a couple of unused members since we no longer generate the shadow DOM from C++
and rename the partOfSnapshotLabel method to partOfSnapshotOverlay.

  • page/ChromeClient.h:

(WebCore::ChromeClient::plugInStartLabelTitle):
(WebCore::ChromeClient::plugInStartLabelSubtitle):
(WebCore::ChromeClient::plugInExtraScript):
Pass in the mime-type to plugInStartLabelTitle and plugInStartLabelSubtitle and expose
a new plugInExtraScript method to allow the chrome client to provide a custom JS file
for the management of the shadow root.

  • rendering/RenderSnapshottedPlugIn.cpp:

(WebCore::RenderSnapshottedPlugIn::handleEvent):
Update the terminology from "label" to "overlay" per the changes made in HTMLPlugInImageElement.

Source/WebKit2:

Expose a new plugInExtraScript method to support the injection of
a JS file from the chrome client to customize the rendering of a
snapshotted plug-in's shadow tree. Additionally, it is expected
the chrome client will want to provide localized strings taking
into account the snapshotted plug-in's mime-type, so we're adding
this as a parameter to both plugInStartLabelTitle and
plugInStartLabelSubtitle methods.

  • WebProcess/InjectedBundle/API/c/WKBundlePage.h:
  • WebProcess/InjectedBundle/InjectedBundlePageUIClient.cpp:

(WebKit::InjectedBundlePageUIClient::plugInStartLabelTitle):
(WebKit::InjectedBundlePageUIClient::plugInStartLabelSubtitle):
(WebKit::InjectedBundlePageUIClient::plugInExtraScript):

  • WebProcess/InjectedBundle/InjectedBundlePageUIClient.h:

(InjectedBundlePageUIClient):

  • WebProcess/WebCoreSupport/WebChromeClient.cpp:

(WebKit::WebChromeClient::plugInStartLabelTitle):
(WebKit::WebChromeClient::plugInStartLabelSubtitle):
(WebKit::WebChromeClient::plugInExtraScript):

  • WebProcess/WebCoreSupport/WebChromeClient.h:

(WebChromeClient):

Tools:

Take into account the new plugInExtraScript method added to support
the injection of a JS file from the chrome client to customize the
rendering of a snapshotted plug-in's shadow tree.

  • WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:

(WTR::InjectedBundlePage::InjectedBundlePage):

Location:
trunk
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r149585 r149586  
     12013-05-06  Antoine Quint  <graouts@apple.com>
     2
     3        Manage the presentation of the snapshotted plug-in using JavaScript
     4        https://bugs.webkit.org/show_bug.cgi?id=115548
     5
     6        Reviewed by Dean Jackson.
     7
     8        * Resources/plugIns.js:
     9        (createOverlay):
     10        Implement the createOverlay(shadowRoot, titleText, subtitleText) method
     11        that is called from WebCore (HTMLPlugInImageElement::didAddUserAgentShadowRoot)
     12        to allow the injected script to customize the shadow root for a snapshotted
     13        plug-in. This is a default implementation, clients are expected to customize
     14        this by providing their own JS file with enhanced behavior.
     15
     16        * css/CSSDefaultStyleSheets.cpp:
     17        (WebCore::CSSDefaultStyleSheets::ensureDefaultStyleSheetsForElement):
     18        Since we no longer have a default shadow tree generated in C++, it makes little
     19        sense for clients to extend the default snapshotted plug-in stylesheet, so we
     20        only insert it if no custom one is provided by the chrome client.
     21
     22        * css/plugIns.css:
     23        Better styling of the default snapshotted plug-in overlay look by using CSS
     24        flex boxes. Also using more explicit selector as an optimization.
     25
     26        * dom/Document.cpp:
     27        (WebCore::Document::ensurePlugInsInjectedScript):
     28        Expose a new method to allow HTMLPlugInImageElement instances to ensure that
     29        the JavaScript code required to customize the snapshotted plug-in's shadow root
     30        is indeed injected in the current document. The actual injection would only
     31        happen once per document so all snapshotted plug-ins share the same scripting
     32        context.
     33
     34        * dom/Document.h:
     35        Expose the new ensurePlugInsInjectedScript method and the m_hasInjectedPlugInsScript
     36        property used to ensure injection happens only once per document.
     37
     38        * html/HTMLPlugInImageElement.cpp:
     39        (WebCore::titleText):
     40        (WebCore::subtitleText):
     41        Store the localized strings for each mime-type in a static hash map as it can be
     42        costly to retrieve them each time from the client. It is expected the chrome client
     43        will want to provide localized strings taking into account the snapshotted plug-in's
     44        mime-type, so we're adding this as a parameter.
     45        (WebCore::HTMLPlugInImageElement::checkSnapshotStatus):
     46        Dispatch a "resize" event to the shadow root to notify the injected script that the
     47        snapshotted plug-in's metrics have changed and to allow the overlay to update itself
     48        as a result.
     49        (WebCore::HTMLPlugInImageElement::didAddUserAgentShadowRoot):
     50        Remove all the DOM generation code in favor of an approach where we create a shared
     51        DOM scripting world in which we inject JavaScript code that will perform the same
     52        task but will additionally be provided by the client in order to provide a completely
     53        custom overlay for the snapshotted plug-in. The sole contract is for the JavaScript
     54        to implement a createOverlay(shadowRoot, titleText, subtitleText) method.
     55        (WebCore::HTMLPlugInImageElement::partOfSnapshotOverlay):
     56        Renamed method to be generic to the overlay as opposed to text labels and use the
     57        element with CSS class name "snapshot-overlay" as the comparison node.
     58
     59        * html/HTMLPlugInImageElement.h:
     60        (HTMLPlugInImageElement):
     61        Removing a couple of unused members since we no longer generate the shadow DOM from C++
     62        and rename the partOfSnapshotLabel method to partOfSnapshotOverlay.
     63
     64        * page/ChromeClient.h:
     65        (WebCore::ChromeClient::plugInStartLabelTitle):
     66        (WebCore::ChromeClient::plugInStartLabelSubtitle):
     67        (WebCore::ChromeClient::plugInExtraScript):
     68        Pass in the mime-type to plugInStartLabelTitle and plugInStartLabelSubtitle and expose
     69        a new plugInExtraScript method to allow the chrome client to provide a custom JS file
     70        for the management of the shadow root.
     71
     72        * rendering/RenderSnapshottedPlugIn.cpp:
     73        (WebCore::RenderSnapshottedPlugIn::handleEvent):
     74        Update the terminology from "label" to "overlay" per the changes made in HTMLPlugInImageElement.
     75
    1762013-05-06  Robert Hogan  <robert@webkit.org>
    277
  • trunk/Source/WebCore/Resources/plugIns.js

    r149578 r149586  
    11
    2 // FIXME: Fill up with useful code for https://webkit.org/b/115548.
    3 undefined;
     2// Function called from WebCore.
     3function createOverlay(shadowRoot, titleText, subtitleText)
     4{
     5    // Generate the following structure:
     6    //
     7    // <div pseudo="-webkit-snapshotted-plugin-content">
     8    //     <div class="snapshot-overlay" aria-label="[Title]: [Subtitle]" role="button">
     9    //         <div class="snapshot-label">
     10    //             <div class="snapshot-title">[Title]</div>
     11    //             <div class="snapshot-subtitle">[Subtitle]</div>
     12    //         </div>
     13    //     </div>
     14    // </div>
     15
     16    var shadowContainer = document.createElement("div");
     17    shadowContainer.setAttribute("pseudo", "-webkit-snapshotted-plugin-content");
     18
     19    var overlay = shadowContainer.appendChild(document.createElement("div"));
     20    overlay.setAttribute("aria-label", titleText + ": " + subtitleText);
     21    overlay.setAttribute("role", "button");
     22    overlay.className = "snapshot-overlay";
     23
     24    var snapshotLabel = overlay.appendChild(document.createElement("div"));
     25    snapshotLabel.className = "snapshot-label";
     26
     27    var title = snapshotLabel.appendChild(document.createElement("div"));
     28    title.className = "snapshot-title";
     29    title.textContent = titleText;
     30
     31    var subtitle = snapshotLabel.appendChild(document.createElement("div"));
     32    subtitle.className = "snapshot-subtitle";
     33    subtitle.textContent = subtitleText;
     34
     35    shadowRoot.appendChild(shadowContainer);
     36};
  • trunk/Source/WebCore/css/CSSDefaultStyleSheets.cpp

    r145876 r149586  
    202202
    203203    if (!plugInsStyleSheet && (element->hasTagName(objectTag) || element->hasTagName(embedTag))) {
    204         String plugInsRules = String(plugInsUserAgentStyleSheet, sizeof(plugInsUserAgentStyleSheet)) + RenderTheme::themeForPage(element->document()->page())->extraPlugInsStyleSheet() + element->document()->page()->chrome()->client()->plugInExtraStyleSheet();
     204        String plugInsRules = RenderTheme::themeForPage(element->document()->page())->extraPlugInsStyleSheet() + element->document()->page()->chrome()->client()->plugInExtraStyleSheet();
     205        if (plugInsRules.isEmpty())
     206            plugInsRules = String(plugInsUserAgentStyleSheet, sizeof(plugInsUserAgentStyleSheet));
    205207        plugInsStyleSheet = parseUASheet(plugInsRules);
    206208        defaultStyle->addRulesFromSheet(plugInsStyleSheet, screenEval());
  • trunk/Source/WebCore/css/plugIns.css

    r143421 r149586  
    3030 *
    3131 * <object>
    32  *   #ShadowRoot
    33  *     <div class="snapshot-container">
    34  *       <div class="snapshot-overlay"></div> <!-- e.g. for dimming content -->
    35  *         <div class="snapshot-label">
    36  *           <div class="snapshot-title">Snapshotted Plug-In</div>
    37  *           <div class="snapshot-subtitle">Click to restart</div>
     32 *     #ShadowRoot
     33 *         <div pseudo="-webkit-snapshotted-plugin-content">
     34 *             <div class="snapshot-overlay" aria-label="[Title]: [Subtitle]" role="button">
     35 *                 <div class="snapshot-label">
     36 *                     <div class="snapshot-title">[Title]</div>
     37 *                     <div class="snapshot-subtitle">[Subtitle]</div>
     38 *                 </div>
     39 *             </div>
    3840 *         </div>
    39  *       </div>
    40  *     </div>
    41  *
    4241 */
    4342
    44 object::-webkit-snapshotted-plugin-content,
    45 embed::-webkit-snapshotted-plugin-content
     43embed::-webkit-snapshotted-plugin-content,
     44object::-webkit-snapshotted-plugin-content
    4645{
    4746    position: relative;
     
    5150}
    5251
    53 object::-webkit-snapshotted-plugin-content .snapshot-container,
    54 embed::-webkit-snapshotted-plugin-content .snapshot-container
     52embed::-webkit-snapshotted-plugin-content > .snapshot-overlay,
     53object::-webkit-snapshotted-plugin-content > .snapshot-overlay
    5554{
    5655    position: absolute;
    57     width: 100%;
    58     height: 100%;
     56    top: 5px;
     57    right: 5px;
     58    bottom: 5px;
     59    left: 5px;
     60    background-color: rgba(255, 255, 255, 0.75);
     61    cursor: pointer;
     62    display: -webkit-flex;
     63    -webkit-justify-content: center;
     64    -webkit-align-items: center;
    5965}
    6066
    61 object::-webkit-snapshotted-plugin-content .snapshot-container .snapshot-overlay,
    62 embed::-webkit-snapshotted-plugin-content .snapshot-container .snapshot-overlay
     67embed::-webkit-snapshotted-plugin-content > .snapshot-overlay > .snapshot-label,
     68object::-webkit-snapshotted-plugin-content > .snapshot-overlay > .snapshot-label
    6369{
    64     display: none;
    65 }
    66 
    67 object::-webkit-snapshotted-plugin-content .snapshot-container .snapshot-label,
    68 embed::-webkit-snapshotted-plugin-content .snapshot-container .snapshot-label
    69 {
    70     position: absolute;
    71     background-color: white;
    7270    color: black;
    73     margin: 1em;
    74     padding: 0.25em 2em;
    75     text-align: center;
    76     cursor: pointer;
    7771    -webkit-user-select: none;
    7872}
    7973
    80 object::-webkit-snapshotted-plugin-content .snapshot-container .snapshot-label .snapshot-title,
    81 embed::-webkit-snapshotted-plugin-content .snapshot-container .snapshot-label .snapshot-title
     74embed::-webkit-snapshotted-plugin-content > .snapshot-overlay > .snapshot-label > div,
     75object::-webkit-snapshotted-plugin-content > .snapshot-overlay > .snapshot-label > div
     76{
     77    overflow: hidden;
     78    white-space: nowrap;
     79    text-overflow: ellipsis;
     80}
     81
     82embed::-webkit-snapshotted-plugin-content > .snapshot-overlay > .snapshot-label > .snapshot-title,
     83object::-webkit-snapshotted-plugin-content > .snapshot-overlay > .snapshot-label > .snapshot-title
    8284{
    8385    font-weight: bold;
    8486}
    8587
    86 object::-webkit-snapshotted-plugin-content .snapshot-container .snapshot-label .snapshot-subtitle,
    87 embed::-webkit-snapshotted-plugin-content .snapshot-container .snapshot-label .snapshot-subtitle
     88embed::-webkit-snapshotted-plugin-content > .snapshot-overlay > .snapshot-label > .snapshot-subtitle,
     89object::-webkit-snapshotted-plugin-content > .snapshot-overlay > .snapshot-label > .snapshot-subtitle
    8890{
    8991    font-style: italic;
  • trunk/Source/WebCore/dom/Document.cpp

    r149583 r149586  
    130130#include "PlatformKeyboardEvent.h"
    131131#include "PlatformLocale.h"
     132#include "PlugInsResources.h"
    132133#include "PluginDocument.h"
    133134#include "PointerLockController.h"
     
    150151#include "ScriptEventListener.h"
    151152#include "ScriptRunner.h"
     153#include "ScriptSourceCode.h"
     154#include "ScriptValue.h"
    152155#include "ScrollingCoordinator.h"
    153156#include "SecurityOrigin.h"
     
    488491#endif
    489492    , m_didAssociateFormControlsTimer(this, &Document::didAssociateFormControlsTimerFired)
     493    , m_hasInjectedPlugInsScript(false)
    490494{
    491495    m_printing = false;
     
    60516055}
    60526056
     6057void Document::ensurePlugInsInjectedScript(DOMWrapperWorld* world)
     6058{
     6059    if (m_hasInjectedPlugInsScript)
     6060        return;
     6061
     6062    // Use the JS file provided by the Chrome client, or fallback to the default one.
     6063    String jsString = page()->chrome()->client()->plugInExtraScript();
     6064    if (!jsString)
     6065        jsString = plugInsJavaScript;
     6066
     6067    page()->mainFrame()->script()->evaluateInWorld(ScriptSourceCode(jsString), world);
     6068
     6069    m_hasInjectedPlugInsScript = true;
     6070}
     6071
    60536072} // namespace WebCore
  • trunk/Source/WebCore/dom/Document.h

    r149392 r149586  
    7979class DOMSelection;
    8080class DOMWindow;
     81class DOMWrapperWorld;
    8182class Database;
    8283class DatabaseThread;
     
    12041205#endif
    12051206
     1207    void ensurePlugInsInjectedScript(DOMWrapperWorld*);
     1208
    12061209protected:
    12071210    Document(Frame*, const KURL&, bool isXHTML, bool isHTML);
     
    15821585    HashSet<RefPtr<Element> > m_associatedFormControls;
    15831586
     1587    bool m_hasInjectedPlugInsScript;
    15841588};
    15851589
  • trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp

    r149469 r149586  
    3131#include "HTMLImageLoader.h"
    3232#include "Image.h"
     33#include "JSDocumentFragment.h"
    3334#include "LocalizedStrings.h"
    3435#include "Logging.h"
     
    5051#include "StyleResolver.h"
    5152#include "Text.h"
     53#include <JavaScriptCore/APICast.h>
     54#include <JavaScriptCore/JSBase.h>
    5255#include <wtf/CurrentTime.h>
     56#include <wtf/HashMap.h>
     57#include <wtf/text/StringHash.h>
    5358
    5459namespace WebCore {
     
    5762
    5863typedef Vector<RefPtr<HTMLPlugInImageElement> > HTMLPlugInImageElementList;
     64typedef HashMap<String, String> MimeTypeToLocalizedStringMap;
    5965
    6066static const int sizingTinyDimensionThreshold = 40;
    61 static const int sizingSmallWidthThreshold = 250;
    62 static const int sizingMediumWidthThreshold = 450;
    63 static const int sizingMediumHeightThreshold = 300;
    6467static const float sizingFullPageAreaRatioThreshold = 0.96;
    6568static const float autostartSoonAfterUserGestureThreshold = 5.0;
     
    6871static const double simulatedMouseClickTimerDelay = .75;
    6972static const double removeSnapshotTimerDelay = 1.5;
     73
     74static const String titleText(Page* page, String mimeType)
     75{
     76    DEFINE_STATIC_LOCAL(MimeTypeToLocalizedStringMap, mimeTypeToLabelTitleMap, ());
     77    String titleText = mimeTypeToLabelTitleMap.get(mimeType);
     78    if (!titleText.isEmpty())
     79        return titleText;
     80
     81    titleText = page->chrome()->client()->plugInStartLabelTitle(mimeType);
     82    if (titleText.isEmpty())
     83        titleText = snapshottedPlugInLabelTitle();
     84    mimeTypeToLabelTitleMap.set(mimeType, titleText);
     85    return titleText;
     86};
     87
     88static const String subtitleText(Page* page, String mimeType)
     89{
     90    DEFINE_STATIC_LOCAL(MimeTypeToLocalizedStringMap, mimeTypeToLabelSubtitleMap, ());
     91    String subtitleText = mimeTypeToLabelSubtitleMap.get(mimeType);
     92    if (!subtitleText.isEmpty())
     93        return subtitleText;
     94
     95    subtitleText = page->chrome()->client()->plugInStartLabelSubtitle(mimeType);
     96    if (subtitleText.isEmpty())
     97        subtitleText = snapshottedPlugInLabelSubtitle();
     98    mimeTypeToLabelSubtitleMap.set(mimeType, subtitleText);
     99    return subtitleText;
     100};
    70101
    71102HTMLPlugInImageElement::HTMLPlugInImageElement(const QualifiedName& tagName, Document* document, bool createdByParser, PreferPlugInsForImagesOption preferPlugInsForImagesOption)
     
    319350}
    320351
    321 static AtomicString classNameForShadowRoot(const Node* node)
    322 {
    323     DEFINE_STATIC_LOCAL(const AtomicString, plugInTinySizeClassName, ("tiny", AtomicString::ConstructFromLiteral));
    324     DEFINE_STATIC_LOCAL(const AtomicString, plugInSmallSizeClassName, ("small", AtomicString::ConstructFromLiteral));
    325     DEFINE_STATIC_LOCAL(const AtomicString, plugInMediumSizeClassName, ("medium", AtomicString::ConstructFromLiteral));
    326     DEFINE_STATIC_LOCAL(const AtomicString, plugInLargeSizeClassName, ("large", AtomicString::ConstructFromLiteral));
    327 
    328     RenderBox* renderBox = static_cast<RenderBox*>(node->renderer());
    329     LayoutUnit width = renderBox->contentWidth();
    330     LayoutUnit height = renderBox->contentHeight();
    331 
    332     if (width < sizingTinyDimensionThreshold || height < sizingTinyDimensionThreshold)
    333         return plugInTinySizeClassName;
    334 
    335     if (width < sizingSmallWidthThreshold)
    336         return plugInSmallSizeClassName;
    337 
    338     if (width < sizingMediumWidthThreshold || height < sizingMediumHeightThreshold)
    339         return plugInMediumSizeClassName;
    340 
    341     return plugInLargeSizeClassName;
    342 }
    343 
    344352void HTMLPlugInImageElement::checkSnapshotStatus()
    345353{
     
    350358    }
    351359
    352     ShadowRoot* root = userAgentShadowRoot();
    353     if (!root)
    354         return;
    355 
    356     Element* shadowContainer = toElement(root->firstChild());
    357     shadowContainer->setAttribute(classAttr, classNameForShadowRoot(this));
     360    // Notify the shadow root that the size changed so that we may update the overlay layout.
     361    ensureUserAgentShadowRoot()->dispatchEvent(Event::create(eventNames().resizeEvent, true, false));
    358362}
    359363
    360364void HTMLPlugInImageElement::didAddUserAgentShadowRoot(ShadowRoot* root)
    361365{
    362     Document* doc = document();
    363 
    364     m_shadowContainer = HTMLDivElement::create(doc);
    365     m_shadowContainer->setPseudo(AtomicString("-webkit-snapshotted-plugin-content", AtomicString::ConstructFromLiteral));
    366 
    367     RefPtr<Element> container = HTMLDivElement::create(doc);
    368     container->setAttribute(classAttr, AtomicString("snapshot-container", AtomicString::ConstructFromLiteral));
    369 
    370     RefPtr<Element> overlay = HTMLDivElement::create(doc);
    371     overlay->setAttribute(classAttr, AtomicString("snapshot-overlay", AtomicString::ConstructFromLiteral));
    372     container->appendChild(overlay, ASSERT_NO_EXCEPTION);
    373 
    374     m_snapshotLabel = HTMLDivElement::create(doc);
    375     m_snapshotLabel->setAttribute(classAttr, AtomicString("snapshot-label", AtomicString::ConstructFromLiteral));
    376 
    377     String titleText = snapshottedPlugInLabelTitle();
    378     String subtitleText = snapshottedPlugInLabelSubtitle();
    379     if (document()->page()) {
    380         String clientTitleText = document()->page()->chrome()->client()->plugInStartLabelTitle();
    381         if (!clientTitleText.isEmpty())
    382             titleText = clientTitleText;
    383         String clientSubtitleText = document()->page()->chrome()->client()->plugInStartLabelSubtitle();
    384         if (!clientSubtitleText.isEmpty())
    385             subtitleText = clientSubtitleText;
    386     }
    387 
    388     RefPtr<Element> title = HTMLDivElement::create(doc);
    389     title->setAttribute(classAttr, AtomicString("snapshot-title", AtomicString::ConstructFromLiteral));
    390     title->appendChild(doc->createTextNode(titleText), ASSERT_NO_EXCEPTION);
    391     m_snapshotLabel->appendChild(title, ASSERT_NO_EXCEPTION);
    392 
    393     RefPtr<Element> subTitle = HTMLDivElement::create(doc);
    394     subTitle->setAttribute(classAttr, AtomicString("snapshot-subtitle", AtomicString::ConstructFromLiteral));
    395     subTitle->appendChild(doc->createTextNode(subtitleText), ASSERT_NO_EXCEPTION);
    396     m_snapshotLabel->appendChild(subTitle, ASSERT_NO_EXCEPTION);
    397 
    398     container->appendChild(m_snapshotLabel, ASSERT_NO_EXCEPTION);
    399 
    400     // Make this into a button for accessibility clients.
    401     String combinedText = titleText;
    402     if (!combinedText.isEmpty() && !subtitleText.isEmpty())
    403         combinedText.append(" ");
    404     combinedText.append(subtitleText);
    405     container->setAttribute(aria_labelAttr, combinedText);
    406     container->setAttribute(roleAttr, "button");
    407 
    408     m_shadowContainer->appendChild(container, ASSERT_NO_EXCEPTION);
    409     root->appendChild(m_shadowContainer, ASSERT_NO_EXCEPTION);
    410 }
    411 
    412 bool HTMLPlugInImageElement::partOfSnapshotLabel(Node* node)
    413 {
    414     return node && (node == m_snapshotLabel.get() || node->isDescendantOf(m_snapshotLabel.get()));
     366    Page* page = document()->page();
     367    if (!page)
     368        return;
     369   
     370    String mimeType = loadedMimeType();
     371
     372    DEFINE_STATIC_LOCAL(RefPtr<DOMWrapperWorld>, isolatedWorld, (DOMWrapperWorld::create(JSDOMWindow::commonVM())));
     373    document()->ensurePlugInsInjectedScript(isolatedWorld.get());
     374
     375    ScriptController* scriptController = page->mainFrame()->script();
     376    JSDOMGlobalObject* globalObject = JSC::jsCast<JSDOMGlobalObject*>(scriptController->globalObject(isolatedWorld.get()));
     377    JSC::ExecState* exec = globalObject->globalExec();
     378
     379    JSC::JSLockHolder lock(exec);
     380
     381    JSC::MarkedArgumentBuffer argList;
     382    argList.append(toJS(exec, globalObject, root));
     383    argList.append(jsString(exec, titleText(page, mimeType)));
     384    argList.append(jsString(exec, subtitleText(page, mimeType)));
     385
     386    // It is expected the JS file provides a createOverlay(shadowRoot, title, subtitle) function.
     387    JSC::JSObject* overlay = globalObject->get(exec, JSC::Identifier(exec, "createOverlay")).toObject(exec);
     388    JSC::CallData callData;
     389    JSC::CallType callType = overlay->methodTable()->getCallData(overlay, callData);
     390    if (callType == JSC::CallTypeNone)
     391        return;
     392
     393    JSC::JSObject* thisObj = globalObject->methodTable()->toThisObject(globalObject, exec);
     394
     395    JSC::call(exec, overlay, callType, callData, thisObj, argList);
     396}
     397
     398bool HTMLPlugInImageElement::partOfSnapshotOverlay(Node* node)
     399{
     400    DEFINE_STATIC_LOCAL(AtomicString, selector, (".snapshot-overlay", AtomicString::ConstructFromLiteral));
     401    RefPtr<Element> snapshotLabel = ensureUserAgentShadowRoot()->querySelector(selector, ASSERT_NO_EXCEPTION);
     402    return node && snapshotLabel && (node == snapshotLabel.get() || node->isDescendantOf(snapshotLabel.get()));
    415403}
    416404
  • trunk/Source/WebCore/html/HTMLPlugInImageElement.h

    r148560 r149586  
    8484
    8585    void setIsPrimarySnapshottedPlugIn(bool);
    86     bool partOfSnapshotLabel(Node*);
     86    bool partOfSnapshotOverlay(Node*);
    8787
    8888    bool needsCheckForSizeChange() const { return m_needsCheckForSizeChange; }
     
    156156    Timer<HTMLPlugInImageElement> m_removeSnapshotTimer;
    157157    RefPtr<Image> m_snapshotImage;
    158     RefPtr<Element> m_shadowContainer;
    159     RefPtr<Element> m_snapshotLabel;
    160158    bool m_createdDuringUserGesture;
    161159    bool m_isRestartedPlugin;
  • trunk/Source/WebCore/page/ChromeClient.h

    r149125 r149586  
    370370    virtual bool isEmptyChromeClient() const { return false; }
    371371
    372     virtual String plugInStartLabelTitle() const { return String(); }
    373     virtual String plugInStartLabelSubtitle() const { return String(); }
     372    virtual String plugInStartLabelTitle(const String& mimeType) const { UNUSED_PARAM(mimeType); return String(); }
     373    virtual String plugInStartLabelSubtitle(const String& mimeType) const { UNUSED_PARAM(mimeType); return String(); }
    374374    virtual String plugInExtraStyleSheet() const { return String(); }
     375    virtual String plugInExtraScript() const { return String(); }
    375376
    376377    // FIXME: Port should return true using heuristic based on scrollable(RenderBox).
  • trunk/Source/WebCore/rendering/RenderSnapshottedPlugIn.cpp

    r148545 r149586  
    174174    if (event->type() == eventNames().clickEvent || (m_isPotentialMouseActivation && event->type() == eventNames().mouseupEvent)) {
    175175        m_isPotentialMouseActivation = false;
    176         bool clickWasOnLabel = plugInImageElement()->partOfSnapshotLabel(event->target()->toNode());
    177         plugInImageElement()->setDisplayState(clickWasOnLabel ? HTMLPlugInElement::Restarting : HTMLPlugInElement::RestartingWithPendingMouseClick);
    178         plugInImageElement()->userDidClickSnapshot(mouseEvent, !clickWasOnLabel);
     176        bool clickWasOnOverlay = plugInImageElement()->partOfSnapshotOverlay(event->target()->toNode());
     177        plugInImageElement()->setDisplayState(clickWasOnOverlay ? HTMLPlugInElement::Restarting : HTMLPlugInElement::RestartingWithPendingMouseClick);
     178        plugInImageElement()->userDidClickSnapshot(mouseEvent, !clickWasOnOverlay);
    179179        event->setDefaultHandled();
    180180    } else if (event->type() == eventNames().mousedownEvent) {
  • trunk/Source/WebKit2/ChangeLog

    r149584 r149586  
     12013-05-06  Antoine Quint  <graouts@apple.com>
     2
     3        Manage the presentation of the snapshotted plug-in using JavaScript
     4        https://bugs.webkit.org/show_bug.cgi?id=115548
     5
     6        Reviewed by Dean Jackson.
     7
     8        Expose a new plugInExtraScript method to support the injection of
     9        a JS file from the chrome client to customize the rendering of a
     10        snapshotted plug-in's shadow tree. Additionally, it is expected
     11        the chrome client will want to provide localized strings taking
     12        into account the snapshotted plug-in's mime-type, so we're adding
     13        this as a parameter to both plugInStartLabelTitle and
     14        plugInStartLabelSubtitle methods.
     15
     16        * WebProcess/InjectedBundle/API/c/WKBundlePage.h:
     17        * WebProcess/InjectedBundle/InjectedBundlePageUIClient.cpp:
     18        (WebKit::InjectedBundlePageUIClient::plugInStartLabelTitle):
     19        (WebKit::InjectedBundlePageUIClient::plugInStartLabelSubtitle):
     20        (WebKit::InjectedBundlePageUIClient::plugInExtraScript):
     21        * WebProcess/InjectedBundle/InjectedBundlePageUIClient.h:
     22        (InjectedBundlePageUIClient):
     23        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
     24        (WebKit::WebChromeClient::plugInStartLabelTitle):
     25        (WebKit::WebChromeClient::plugInStartLabelSubtitle):
     26        (WebKit::WebChromeClient::plugInExtraScript):
     27        * WebProcess/WebCoreSupport/WebChromeClient.h:
     28        (WebChromeClient):
     29
    1302013-05-05  Chris Fleizach  <cfleizach@apple.com>
    231
  • trunk/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h

    r149417 r149586  
    251251typedef void (*WKBundlePageReachedAppCacheOriginQuotaCallback)(WKBundlePageRef page, WKSecurityOriginRef origin, int64_t totalBytesNeeded, const void *clientInfo);
    252252typedef uint64_t (*WKBundlePageExceededDatabaseQuotaCallback)(WKBundlePageRef page, WKSecurityOriginRef origin, WKStringRef databaseName, WKStringRef databaseDisplayName, uint64_t currentQuotaBytes, uint64_t currentOriginUsageBytes, uint64_t currentDatabaseUsageBytes, uint64_t expectedUsageBytes, const void *clientInfo);
    253 typedef WKStringRef (*WKBundlePagePlugInCreateStartLabelTitleCallback)(const void *clientInfo);
    254 typedef WKStringRef (*WKBundlePagePlugInCreateStartLabelSubtitleCallback)(const void *clientInfo);
     253typedef WKStringRef (*WKBundlePagePlugInCreateStartLabelTitleCallback)(WKStringRef mimeType, const void *clientInfo);
     254typedef WKStringRef (*WKBundlePagePlugInCreateStartLabelSubtitleCallback)(WKStringRef mimeType, const void *clientInfo);
    255255typedef WKStringRef (*WKBundlePagePlugInCreateExtraStyleSheetCallback)(const void *clientInfo);
     256typedef WKStringRef (*WKBundlePagePlugInCreateExtraScriptCallback)(const void *clientInfo);
    256257
    257258struct WKBundlePageUIClient {
     
    281282    WKBundlePagePlugInCreateStartLabelSubtitleCallback                  createPlugInStartLabelSubtitle;
    282283    WKBundlePagePlugInCreateExtraStyleSheetCallback                     createPlugInExtraStyleSheet;
     284    WKBundlePagePlugInCreateExtraScriptCallback                         createPlugInExtraScript;
    283285};
    284286typedef struct WKBundlePageUIClient WKBundlePageUIClient;
  • trunk/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageUIClient.cpp

    r142507 r149586  
    164164}
    165165
    166 String InjectedBundlePageUIClient::plugInStartLabelTitle() const
     166String InjectedBundlePageUIClient::plugInStartLabelTitle(const String& mimeType) const
    167167{
    168168    if (!m_client.createPlugInStartLabelTitle)
    169169        return String();
    170170
    171     RefPtr<WebString> title = adoptRef(toImpl(m_client.createPlugInStartLabelTitle(m_client.clientInfo)));
     171    RefPtr<WebString> title = adoptRef(toImpl(m_client.createPlugInStartLabelTitle(toAPI(mimeType.impl()), m_client.clientInfo)));
    172172    return title ? title->string() : String();
    173173}
    174174
    175 String InjectedBundlePageUIClient::plugInStartLabelSubtitle() const
     175String InjectedBundlePageUIClient::plugInStartLabelSubtitle(const String& mimeType) const
    176176{
    177177    if (!m_client.createPlugInStartLabelSubtitle)
    178178        return String();
    179179
    180     RefPtr<WebString> subtitle = adoptRef(toImpl(m_client.createPlugInStartLabelSubtitle(m_client.clientInfo)));
     180    RefPtr<WebString> subtitle = adoptRef(toImpl(m_client.createPlugInStartLabelSubtitle(toAPI(mimeType.impl()), m_client.clientInfo)));
    181181    return subtitle ? subtitle->string() : String();
    182182}
     
    191191}
    192192
     193String InjectedBundlePageUIClient::plugInExtraScript() const
     194{
     195    if (!m_client.createPlugInExtraScript)
     196        return String();
     197
     198    RefPtr<WebString> script = adoptRef(toImpl(m_client.createPlugInExtraScript(m_client.clientInfo)));
     199    return script ? script->string() : String();
     200}
     201
    193202} // namespace WebKit
  • trunk/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageUIClient.h

    r142507 r149586  
    7171    uint64_t didExceedDatabaseQuota(WebPage*, WebSecurityOrigin*, const String& databaseName, const String& databaseDisplayName, uint64_t currentQuotaBytes, uint64_t currentOriginUsageBytes, uint64_t currentDatabaseUsageBytes, uint64_t expectedUsageBytes);
    7272
    73     String plugInStartLabelTitle() const;
    74     String plugInStartLabelSubtitle() const;
     73    String plugInStartLabelTitle(const String& mimeType) const;
     74    String plugInStartLabelSubtitle(const String& mimeType) const;
    7575    String plugInExtraStyleSheet() const;
     76    String plugInExtraScript() const;
    7677
    7778};
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp

    r149317 r149586  
    825825}
    826826
    827 String WebChromeClient::plugInStartLabelTitle() const
    828 {
    829     return m_page->injectedBundleUIClient().plugInStartLabelTitle();
    830 }
    831 
    832 String WebChromeClient::plugInStartLabelSubtitle() const
    833 {
    834     return m_page->injectedBundleUIClient().plugInStartLabelSubtitle();
     827String WebChromeClient::plugInStartLabelTitle(const String& mimeType) const
     828{
     829    return m_page->injectedBundleUIClient().plugInStartLabelTitle(mimeType);
     830}
     831
     832String WebChromeClient::plugInStartLabelSubtitle(const String& mimeType) const
     833{
     834    return m_page->injectedBundleUIClient().plugInStartLabelSubtitle(mimeType);
    835835}
    836836
     
    840840}
    841841
     842String WebChromeClient::plugInExtraScript() const
     843{
     844    return m_page->injectedBundleUIClient().plugInExtraScript();
     845}
     846
    842847} // namespace WebKit
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h

    r149125 r149586  
    220220    virtual void logDiagnosticMessage(const String& message, const String& description, const String& success) OVERRIDE;
    221221
    222     virtual String plugInStartLabelTitle() const OVERRIDE;
    223     virtual String plugInStartLabelSubtitle() const OVERRIDE;
     222    virtual String plugInStartLabelTitle(const String& mimeType) const OVERRIDE;
     223    virtual String plugInStartLabelSubtitle(const String& mimeType) const OVERRIDE;
    224224    virtual String plugInExtraStyleSheet() const OVERRIDE;
     225    virtual String plugInExtraScript() const OVERRIDE;
    225226
    226227    String m_cachedToolTip;
  • trunk/Tools/ChangeLog

    r149579 r149586  
     12013-05-06  Antoine Quint  <graouts@apple.com>
     2
     3        Manage the presentation of the snapshotted plug-in using JavaScript
     4        https://bugs.webkit.org/show_bug.cgi?id=115548
     5
     6        Reviewed by Dean Jackson.
     7
     8        Take into account the new plugInExtraScript method added to support
     9        the injection of a JS file from the chrome client to customize the
     10        rendering of a snapshotted plug-in's shadow tree.
     11
     12        * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
     13        (WTR::InjectedBundlePage::InjectedBundlePage):
     14
    1152013-05-05  Anders Carlsson  <andersca@apple.com>
    216
  • trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp

    r147260 r149586  
    373373        0, /*plugInStartLabelSubtitle*/
    374374        0, /*plugInExtraStyleSheet*/
     375        0, /*plugInExtraScript*/
    375376    };
    376377    WKBundlePageSetUIClient(m_page, &uiClient);
Note: See TracChangeset for help on using the changeset viewer.