void HTMLPlugInImageElement::restartSimilarPlugIns() { // Restart any other snapshotted plugins in the page with the same origin. Note that they // may be in different frames, so traverse from the top of the document. String plugInOrigin = m_loadedUrl.host(); String mimeType = loadedMimeType(); HTMLPlugInImageElementList pluginsNeedingRestart; if (!document()->page()) return; for (Frame* frame = document()->page()->mainFrame(); frame; frame = frame->tree()->traverseNext()) { if (frame->loader()->subframeLoader()->containsPlugins()) { if (!frame->document()) continue; RefPtr<NodeList> plugins = frame->document()->getElementsByTagName(embedTag.localName()); if (plugins) addPlugInsFromNodeListMatchingPlugInOrigin(pluginsNeedingRestart, plugins, plugInOrigin, mimeType); plugins = frame->document()->getElementsByTagName(objectTag.localName()); if (plugins) addPlugInsFromNodeListMatchingPlugInOrigin(pluginsNeedingRestart, plugins, plugInOrigin, mimeType); } } for (size_t i = 0, length = pluginsNeedingRestart.size(); i < length; i++) { pluginsNeedingRestart[i]->setDisplayState(Playing); pluginsNeedingRestart[i]->restartSnapshottedPlugIn(); } }
void HTMLPlugInImageElement::restartSimilarPlugIns() { // Restart any other snapshotted plugins in the page with the same origin. Note that they // may be in different frames, so traverse from the top of the document. String plugInOrigin = m_loadedUrl.host(); String mimeType = loadedMimeType(); HTMLPlugInImageElementList similarPlugins; if (!document()->page()) return; for (Frame* frame = document()->page()->mainFrame(); frame; frame = frame->tree()->traverseNext()) { if (!frame->loader()->subframeLoader()->containsPlugins()) continue; if (!frame->document()) continue; RefPtr<NodeList> plugIns = frame->document()->getElementsByTagName(embedTag.localName()); if (plugIns) addPlugInsFromNodeListMatchingPlugInOrigin(similarPlugins, plugIns, plugInOrigin, mimeType); plugIns = frame->document()->getElementsByTagName(objectTag.localName()); if (plugIns) addPlugInsFromNodeListMatchingPlugInOrigin(similarPlugins, plugIns, plugInOrigin, mimeType); } for (size_t i = 0, length = similarPlugins.size(); i < length; ++i) { HTMLPlugInImageElement* plugInToRestart = similarPlugins[i].get(); if (plugInToRestart->displayState() <= HTMLPlugInElement::DisplayingSnapshot) { LOG(Plugins, "%p Plug-in looks similar to a restarted plug-in. Restart.", plugInToRestart); plugInToRestart->setDisplayState(Playing); plugInToRestart->restartSnapshottedPlugIn(); } plugInToRestart->m_snapshotDecision = NeverSnapshot; } }
void HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn(const KURL& url) { LOG(Plugins, "%p Plug-in URL: %s", this, m_url.utf8().data()); LOG(Plugins, " Loaded URL: %s", url.string().utf8().data()); m_loadedUrl = url; m_plugInWasCreated = false; m_deferredPromotionToPrimaryPlugIn = false; if (!document()->page() || !document()->page()->settings()->plugInSnapshottingEnabled()) { m_snapshotDecision = NeverSnapshot; return; } if (displayState() == Restarting) { LOG(Plugins, "%p Plug-in is explicitly restarting", this); m_snapshotDecision = NeverSnapshot; setDisplayState(Playing); return; } if (displayState() == RestartingWithPendingMouseClick) { LOG(Plugins, "%p Plug-in is explicitly restarting but also waiting for a click", this); m_snapshotDecision = NeverSnapshot; return; } if (m_snapshotDecision == NeverSnapshot) { LOG(Plugins, "%p Plug-in is blessed, allow it to start", this); return; } bool inMainFrame = document()->frame() == document()->page()->mainFrame(); if (document()->isPluginDocument() && inMainFrame) { LOG(Plugins, "%p Plug-in document in main frame", this); m_snapshotDecision = NeverSnapshot; return; } if (ScriptController::processingUserGesture()) { LOG(Plugins, "%p Script is currently processing user gesture, set to play", this); m_snapshotDecision = NeverSnapshot; return; } if (m_createdDuringUserGesture) { LOG(Plugins, "%p Plug-in was created when processing user gesture, set to play", this); m_snapshotDecision = NeverSnapshot; return; } if (documentHadRecentUserGesture(document())) { LOG(Plugins, "%p Plug-in was created shortly after a user gesture, set to play", this); m_snapshotDecision = NeverSnapshot; return; } if (document()->page()->settings()->snapshotAllPlugIns()) { LOG(Plugins, "%p Plug-in forced to snapshot by user preference", this); m_snapshotDecision = Snapshotted; setDisplayState(WaitingForSnapshot); return; } if (document()->page()->settings()->autostartOriginPlugInSnapshottingEnabled() && document()->page()->plugInClient() && document()->page()->plugInClient()->shouldAutoStartFromOrigin(document()->page()->mainFrame()->document()->baseURL().host(), url.host(), loadedMimeType())) { LOG(Plugins, "%p Plug-in from (%s, %s) is marked to auto-start, set to play", this, document()->page()->mainFrame()->document()->baseURL().host().utf8().data(), url.host().utf8().data()); m_snapshotDecision = NeverSnapshot; return; } RenderBox* renderEmbeddedObject = toRenderBox(renderer()); Length styleWidth = renderEmbeddedObject->style()->width(); Length styleHeight = renderEmbeddedObject->style()->height(); LayoutRect contentBoxRect = renderEmbeddedObject->contentBoxRect(); int contentWidth = contentBoxRect.width(); int contentHeight = contentBoxRect.height(); int contentArea = contentWidth * contentHeight; IntSize visibleViewSize = document()->frame()->view()->visibleSize(); int visibleArea = visibleViewSize.width() * visibleViewSize.height(); if (inMainFrame && styleWidth.isPercent() && (styleWidth.percent() == 100) && styleHeight.isPercent() && (styleHeight.percent() == 100) && (static_cast<float>(contentArea) / visibleArea > sizingFullPageAreaRatioThreshold)) { LOG(Plugins, "%p Plug-in is top level full page, set to play", this); m_snapshotDecision = NeverSnapshot; return; } if (contentWidth <= sizingTinyDimensionThreshold || contentHeight <= sizingTinyDimensionThreshold) { LOG(Plugins, "%p Plug-in is very small %dx%d, set to play", this, contentWidth, contentHeight); m_sizeWhenSnapshotted = IntSize(contentBoxRect.width().toInt(), contentBoxRect.height().toInt()); m_snapshotDecision = MaySnapshotWhenResized; return; } if (!document()->page()->plugInClient()) { LOG(Plugins, "%p There is no plug-in client. Set to wait for snapshot", this); m_snapshotDecision = NeverSnapshot; setDisplayState(WaitingForSnapshot); return; } LOG(Plugins, "%p Plug-in from (%s, %s) is not auto-start, sized at %dx%d, set to wait for snapshot", this, document()->page()->mainFrame()->document()->baseURL().host().utf8().data(), url.host().utf8().data(), contentWidth, contentHeight); m_snapshotDecision = Snapshotted; setDisplayState(WaitingForSnapshot); }
void HTMLPlugInImageElement::userDidClickSnapshot(PassRefPtr<MouseEvent> event, bool forwardEvent) { if (forwardEvent) m_pendingClickEventFromSnapshot = event; String plugInOrigin = m_loadedUrl.host(); if (document()->page() && !SchemeRegistry::shouldTreatURLSchemeAsLocal(document()->page()->mainFrame()->document()->baseURL().protocol()) && document()->page()->settings()->autostartOriginPlugInSnapshottingEnabled()) document()->page()->plugInClient()->didStartFromOrigin(document()->page()->mainFrame()->document()->baseURL().host(), plugInOrigin, loadedMimeType()); LOG(Plugins, "%p User clicked on snapshotted plug-in. Restart.", this); restartSnapshottedPlugIn(); restartSimilarPlugIns(); }
void HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn(const KURL& url) { LOG(Plugins, "%p Plug-in URL: %s", this, m_url.utf8().data()); LOG(Plugins, " Loaded URL: %s", url.string().utf8().data()); m_loadedUrl = url; if (!document()->page() || !document()->page()->settings()->plugInSnapshottingEnabled()) return; if (displayState() == Restarting) { setDisplayState(Playing); LOG(Plugins, "%p Plug-in is explicitly restarting", this); return; } if (displayState() == RestartingWithPendingMouseClick) { LOG(Plugins, "%p Plug-in is explicitly restarting but also waiting for a click", this); return; } bool inMainFrame = document()->frame() == document()->page()->mainFrame(); if (document()->isPluginDocument() && inMainFrame) { LOG(Plugins, "%p Plug-in document in main frame", this); return; } if (ScriptController::processingUserGesture()) { LOG(Plugins, "%p Script is currently processing user gesture, set to play", this); return; } if (m_createdDuringUserGesture) { LOG(Plugins, "%p Plug-in was created when processing user gesture, set to play", this); return; } double lastKnownUserGestureTimestamp = document()->lastHandledUserGestureTimestamp(); if (!inMainFrame && document()->page()->mainFrame() && document()->page()->mainFrame()->document()) lastKnownUserGestureTimestamp = std::max(lastKnownUserGestureTimestamp, document()->page()->mainFrame()->document()->lastHandledUserGestureTimestamp()); if (currentTime() - lastKnownUserGestureTimestamp < autostartSoonAfterUserGestureThreshold) { LOG(Plugins, "%p Plug-in was created shortly after a user gesture, set to play", this); return; } RenderBox* renderEmbeddedObject = toRenderBox(renderer()); Length styleWidth = renderEmbeddedObject->style()->width(); Length styleHeight = renderEmbeddedObject->style()->height(); LayoutRect contentBoxRect = renderEmbeddedObject->contentBoxRect(); int contentWidth = contentBoxRect.width(); int contentHeight = contentBoxRect.height(); int contentArea = contentWidth * contentHeight; IntSize visibleViewSize = document()->frame()->view()->visibleSize(); int visibleArea = visibleViewSize.width() * visibleViewSize.height(); if (inMainFrame && styleWidth.isPercent() && (styleWidth.percent() == 100) && styleHeight.isPercent() && (styleHeight.percent() == 100) && (static_cast<float>(contentArea) / visibleArea > sizingFullPageAreaRatioThreshold)) { LOG(Plugins, "%p Plug-in is top level full page, set to play", this); return; } if (contentWidth <= sizingTinyDimensionThreshold || contentHeight <= sizingTinyDimensionThreshold) { LOG(Plugins, "%p Plug-in is very small %dx%d, set to play", this, contentWidth, contentHeight); return; } if (!document()->page()->plugInClient()) { setDisplayState(WaitingForSnapshot); return; } if (document()->page()->plugInClient()->shouldAutoStartFromOrigin(document()->page()->mainFrame()->document()->baseURL().host(), url.host(), loadedMimeType())) { LOG(Plugins, "%p Plug-in from (%s, %s) is marked to auto-start, set to play", this, document()->page()->mainFrame()->document()->baseURL().host().utf8().data(), url.host().utf8().data()); return; } LOG(Plugins, "%p Plug-in from (%s, %s) is not auto-start, sized at %dx%d, set to wait for snapshot", this, document()->page()->mainFrame()->document()->baseURL().host().utf8().data(), url.host().utf8().data(), contentWidth, contentHeight); setDisplayState(WaitingForSnapshot); }
void HTMLPlugInImageElement::userDidClickSnapshot(PassRefPtr<MouseEvent> event) { m_pendingClickEventFromSnapshot = event; String plugInOrigin = m_loadedUrl.host(); if (document()->page() && !SchemeRegistry::shouldTreatURLSchemeAsLocal(document()->page()->mainFrame()->document()->baseURL().protocol())) document()->page()->plugInClient()->didStartFromOrigin(document()->page()->mainFrame()->document()->baseURL().host(), plugInOrigin, loadedMimeType()); restartSnapshottedPlugIn(); restartSimilarPlugIns(); }