1/*
2 * Copyright (C) 2008, 2009, 2011, 2012, 2014 Apple Inc. All rights reserved.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB.  If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 *
19 */
20
21#ifndef HTMLPlugInImageElement_h
22#define HTMLPlugInImageElement_h
23
24#include "HTMLPlugInElement.h"
25
26namespace WebCore {
27
28class HTMLImageLoader;
29class FrameLoader;
30class Image;
31class MouseEvent;
32class RenderStyle;
33class Widget;
34
35enum PluginCreationOption {
36    CreateAnyWidgetType,
37    CreateOnlyNonNetscapePlugins,
38};
39
40// Base class for HTMLAppletElement, HTMLEmbedElement, and HTMLObjectElement.
41// FIXME: Should HTMLAppletElement inherit from HTMLPlugInElement directly instead?
42class HTMLPlugInImageElement : public HTMLPlugInElement {
43public:
44    virtual ~HTMLPlugInImageElement();
45
46    RenderEmbeddedObject* renderEmbeddedObject() const;
47
48    virtual void setDisplayState(DisplayState) override;
49
50    virtual void updateWidget(PluginCreationOption) = 0;
51
52    const String& serviceType() const { return m_serviceType; }
53    const String& url() const { return m_url; }
54    const URL& loadedUrl() const { return m_loadedUrl; }
55
56    const String loadedMimeType() const
57    {
58        String mimeType = serviceType();
59        if (mimeType.isEmpty())
60            mimeType = mimeTypeFromURL(m_loadedUrl);
61        return mimeType;
62    }
63
64    bool shouldPreferPlugInsForImages() const { return m_shouldPreferPlugInsForImages; }
65
66    // Public for FrameView::addWidgetToUpdate()
67    bool needsWidgetUpdate() const { return m_needsWidgetUpdate; }
68    void setNeedsWidgetUpdate(bool needsWidgetUpdate) { m_needsWidgetUpdate = needsWidgetUpdate; }
69
70    void userDidClickSnapshot(PassRefPtr<MouseEvent>, bool forwardEvent);
71    void checkSnapshotStatus();
72    Image* snapshotImage() const { return m_snapshotImage.get(); }
73    void restartSnapshottedPlugIn();
74
75    // Plug-in URL might not be the same as url() with overriding parameters.
76    void subframeLoaderWillCreatePlugIn(const URL& plugInURL);
77    void subframeLoaderDidCreatePlugIn(const Widget*);
78
79    void setIsPrimarySnapshottedPlugIn(bool);
80    bool partOfSnapshotOverlay(Node*);
81
82    bool needsCheckForSizeChange() const { return m_needsCheckForSizeChange; }
83    void setNeedsCheckForSizeChange() { m_needsCheckForSizeChange = true; }
84    void checkSizeChangeForSnapshotting();
85
86    enum SnapshotDecision {
87        SnapshotNotYetDecided,
88        NeverSnapshot,
89        Snapshotted,
90        MaySnapshotWhenResized,
91        MaySnapshotWhenContentIsSet
92    };
93    SnapshotDecision snapshotDecision() const { return m_snapshotDecision; }
94
95protected:
96    enum PreferPlugInsForImagesOption { ShouldPreferPlugInsForImages, ShouldNotPreferPlugInsForImages };
97    HTMLPlugInImageElement(const QualifiedName& tagName, Document&, bool createdByParser, PreferPlugInsForImagesOption);
98
99    virtual void didMoveToNewDocument(Document* oldDocument) override;
100    virtual bool requestObject(const String& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues) override final;
101
102    bool isImageType();
103    HTMLImageLoader* imageLoader() { return m_imageLoader.get(); }
104
105    bool allowedToLoadFrameURL(const String& url);
106    bool wouldLoadAsNetscapePlugin(const String& url, const String& serviceType);
107
108    String m_serviceType;
109    String m_url;
110
111    std::unique_ptr<HTMLImageLoader> m_imageLoader;
112
113private:
114    virtual bool isPlugInImageElement() const override final { return true; }
115    virtual bool isRestartedPlugin() const override final { return m_isRestartedPlugin; }
116
117    virtual void finishParsingChildren() override final;
118    virtual void didAddUserAgentShadowRoot(ShadowRoot*) override final;
119
120    virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
121    virtual bool willRecalcStyle(Style::Change) override final;
122    virtual void didAttachRenderers() override final;
123    virtual void willDetachRenderers() override final;
124
125    virtual void documentWillSuspendForPageCache() override final;
126    virtual void documentDidResumeFromPageCache() override final;
127
128    virtual void defaultEventHandler(Event*) override final;
129    virtual void dispatchPendingMouseClick() override final;
130
131    virtual void updateSnapshot(PassRefPtr<Image>) override final;
132
133    void startLoadingImage();
134    void updateWidgetIfNecessary();
135
136    void simulatedMouseClickTimerFired();
137
138    void restartSimilarPlugIns();
139    void removeSnapshotTimerFired(Timer<HTMLPlugInImageElement>&);
140    bool isTopLevelFullPagePlugin(const RenderEmbeddedObject&) const;
141
142    URL m_loadedUrl;
143    bool m_needsWidgetUpdate;
144    bool m_shouldPreferPlugInsForImages;
145    bool m_needsDocumentActivationCallbacks;
146    RefPtr<MouseEvent> m_pendingClickEventFromSnapshot;
147    DeferrableOneShotTimer m_simulatedMouseClickTimer;
148    Timer<HTMLPlugInImageElement> m_removeSnapshotTimer;
149    RefPtr<Image> m_snapshotImage;
150    bool m_createdDuringUserGesture;
151    bool m_isRestartedPlugin;
152    bool m_needsCheckForSizeChange;
153    bool m_plugInWasCreated;
154    bool m_deferredPromotionToPrimaryPlugIn;
155    IntSize m_sizeWhenSnapshotted;
156    SnapshotDecision m_snapshotDecision;
157    bool m_plugInDimensionsSpecified;
158};
159
160void isHTMLPlugInImageElement(const HTMLPlugInImageElement&); // Catch unnecessary runtime check of type known at compile time.
161inline bool isHTMLPlugInImageElement(const HTMLPlugInElement& element) { return element.isPlugInImageElement(); }
162inline bool isHTMLPlugInImageElement(const Node& node) { return node.isPluginElement() && toHTMLPlugInElement(node).isPlugInImageElement(); }
163template <> inline bool isElementOfType<const HTMLPlugInImageElement>(const Element& element) { return isHTMLPlugInImageElement(element); }
164NODE_TYPE_CASTS(HTMLPlugInImageElement)
165
166} // namespace WebCore
167
168#endif // HTMLPlugInImageElement_h
169