void Page::refreshPlugins(bool reload) { if (allPages().isEmpty()) return; PluginData::refresh(); Vector<RefPtr<LocalFrame> > framesNeedingReload; HashSet<Page*>::iterator end = allPages().end(); for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it) { Page* page = *it; // Clear out the page's plug-in data. if (page->m_pluginData) page->m_pluginData = nullptr; if (!reload) continue; for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) { if (frame->isLocalFrame() && toLocalFrame(frame)->document()->containsPlugins()) framesNeedingReload.append(toLocalFrame(frame)); } } for (size_t i = 0; i < framesNeedingReload.size(); ++i) framesNeedingReload[i]->loader().reload(); }
void WebPagePopupImpl::closePopup() { { // This function can be called in EventDispatchForbiddenScope for the main // document, and the following operations dispatch some events. It's safe // because web authors can't listen the events. EventDispatchForbiddenScope::AllowUserAgentEvents allowEvents; if (m_page) { toLocalFrame(m_page->mainFrame())->loader().stopAllLoaders(); PagePopupSupplement::uninstall(*toLocalFrame(m_page->mainFrame())); } bool closeAlreadyCalled = m_closing; m_closing = true; destroyPage(); // m_widgetClient might be 0 because this widget might be already closed. if (m_widgetClient && !closeAlreadyCalled) { // closeWidgetSoon() will call this->close() later. m_widgetClient->closeWidgetSoon(); } } m_popupClient->didClosePopup(); m_webView->cleanupPagePopup(); }
void Page::willBeDestroyed() { RefPtr<Frame> mainFrame = m_mainFrame; if (mainFrame->isLocalFrame()) toLocalFrame(mainFrame.get())->loader().frameDetached(); // Disable all agents prior to resetting the frame view. m_inspectorController->willBeDestroyed(); if (mainFrame->isLocalFrame()) { toLocalFrame(mainFrame.get())->setView(nullptr); } else { ASSERT(m_mainFrame->isRemoteFrame()); toRemoteFrame(mainFrame.get())->setView(nullptr); } allPages().remove(this); if (ordinaryPages().contains(this)) ordinaryPages().remove(this); if (m_scrollingCoordinator) m_scrollingCoordinator->willBeDestroyed(); #ifndef NDEBUG pageCounter.decrement(); #endif m_chrome->willBeDestroyed(); m_mainFrame = 0; if (m_validationMessageClient) m_validationMessageClient->willBeDestroyed(); WillBeHeapSupplementable<Page>::willBeDestroyed(); }
WebInputEventResult WebPagePopupImpl::handleKeyEvent( const WebKeyboardEvent& event) { if (m_closing || !m_page->mainFrame() || !toLocalFrame(m_page->mainFrame())->view()) return WebInputEventResult::NotHandled; return toLocalFrame(m_page->mainFrame())->eventHandler().keyEvent(event); }
void createWindowForRequest(const FrameLoadRequest& request, LocalFrame& openerFrame, NavigationPolicy policy) { ASSERT(request.resourceRequest().requestorOrigin() || (openerFrame.document() && openerFrame.document()->url().isEmpty())); if (openerFrame.document()->pageDismissalEventBeingDispatched() != Document::NoDismissal) return; if (openerFrame.document() && openerFrame.document()->isSandboxed(SandboxPopups)) return; if (!LocalDOMWindow::allowPopUp(openerFrame)) return; if (policy == NavigationPolicyCurrentTab) policy = NavigationPolicyNewForegroundTab; WindowFeatures features; features.noopener = request.getShouldSetOpener() == NeverSetOpener; bool created; Frame* newFrame = createWindowHelper(openerFrame, openerFrame, openerFrame, request, features, policy, created); if (!newFrame) return; if (request.getShouldSendReferrer() == MaybeSendReferrer) { // TODO(japhet): Does ReferrerPolicy need to be proagated for RemoteFrames? if (newFrame->isLocalFrame()) toLocalFrame(newFrame)->document()->setReferrerPolicy(openerFrame.document()->getReferrerPolicy()); } // TODO(japhet): Form submissions on RemoteFrames don't work yet. FrameLoadRequest newRequest(0, request.resourceRequest()); newRequest.setForm(request.form()); if (newFrame->isLocalFrame()) toLocalFrame(newFrame)->loader().load(newRequest); }
void PaintLayerCompositor::updateIfNeededRecursive() { FrameView* view = m_layoutView.frameView(); if (view->shouldThrottleRendering()) return; for (Frame* child = m_layoutView.frameView()->frame().tree().firstChild(); child; child = child->tree().nextSibling()) { if (!child->isLocalFrame()) continue; LocalFrame* localFrame = toLocalFrame(child); // It's possible for trusted Pepper plugins to force hit testing in situations where // the frame tree is in an inconsistent state, such as in the middle of frame detach. // TODO(bbudge) Remove this check when trusted Pepper plugins are gone. if (localFrame->document()->isActive()) localFrame->contentLayoutObject()->compositor()->updateIfNeededRecursive(); } TRACE_EVENT0("blink", "PaintLayerCompositor::updateIfNeededRecursive"); ASSERT(!m_layoutView.needsLayout()); ScriptForbiddenScope forbidScript; // FIXME: enableCompositingModeIfNeeded can trigger a CompositingUpdateRebuildTree, // which asserts that it's not InCompositingUpdate. enableCompositingModeIfNeeded(); if (m_needsUpdateDescendantDependentFlags) { updateDescendantDependentFlagsForEntireSubtree(*rootLayer()); m_needsUpdateDescendantDependentFlags = false; } m_layoutView.commitPendingSelection(); lifecycle().advanceTo(DocumentLifecycle::InCompositingUpdate); updateIfNeeded(); lifecycle().advanceTo(DocumentLifecycle::CompositingClean); DocumentAnimations::updateCompositorAnimations(m_layoutView.document()); m_layoutView.frameView()->scrollableArea()->updateCompositorScrollAnimations(); if (const FrameView::ScrollableAreaSet* animatingScrollableAreas = m_layoutView.frameView()->animatingScrollableAreas()) { for (ScrollableArea* scrollableArea : *animatingScrollableAreas) scrollableArea->updateCompositorScrollAnimations(); } #if ENABLE(ASSERT) ASSERT(lifecycle().state() == DocumentLifecycle::CompositingClean); assertNoUnresolvedDirtyBits(); for (Frame* child = m_layoutView.frameView()->frame().tree().firstChild(); child; child = child->tree().nextSibling()) { if (!child->isLocalFrame()) continue; LocalFrame* localFrame = toLocalFrame(child); if (localFrame->shouldThrottleRendering()) continue; localFrame->contentLayoutObject()->compositor()->assertNoUnresolvedDirtyBits(); } #endif }
void WindowProxy::updateActivityLogger() { m_scriptState->perContextData()->setActivityLogger( V8DOMActivityLogger::activityLogger( m_world->worldId(), m_frame->isLocalFrame() && toLocalFrame(m_frame)->document() ? toLocalFrame(m_frame)->document()->baseURI() : KURL())); }
bool WebDevToolsAgentImpl::handleInputEvent(blink::Page* page, const WebInputEvent& inputEvent) { if (!m_attached && !m_generatingEvent) return false; // FIXME: This workaround is required for touch emulation on Mac, where // compositor-side pinch handling is not enabled. See http://crbug.com/138003. bool isPinch = inputEvent.type == WebInputEvent::GesturePinchBegin || inputEvent.type == WebInputEvent::GesturePinchUpdate || inputEvent.type == WebInputEvent::GesturePinchEnd; if (isPinch && m_touchEventEmulationEnabled) { FrameView* frameView = page->deprecatedLocalMainFrame()->view(); PlatformGestureEventBuilder gestureEvent(frameView, static_cast<const WebGestureEvent&>(inputEvent)); float pageScaleFactor = page->pageScaleFactor(); if (gestureEvent.type() == PlatformEvent::GesturePinchBegin) { m_lastPinchAnchorCss = adoptPtr(new blink::IntPoint(frameView->scrollPosition() + gestureEvent.position())); m_lastPinchAnchorDip = adoptPtr(new blink::IntPoint(gestureEvent.position())); m_lastPinchAnchorDip->scale(pageScaleFactor, pageScaleFactor); } if (gestureEvent.type() == PlatformEvent::GesturePinchUpdate && m_lastPinchAnchorCss) { float newPageScaleFactor = pageScaleFactor * gestureEvent.scale(); blink::IntPoint anchorCss(*m_lastPinchAnchorDip.get()); anchorCss.scale(1.f / newPageScaleFactor, 1.f / newPageScaleFactor); m_webViewImpl->setPageScaleFactor(newPageScaleFactor); m_webViewImpl->setMainFrameScrollOffset(*m_lastPinchAnchorCss.get() - toIntSize(anchorCss)); } if (gestureEvent.type() == PlatformEvent::GesturePinchEnd) { m_lastPinchAnchorCss.clear(); m_lastPinchAnchorDip.clear(); } return true; } InspectorController* ic = inspectorController(); if (!ic) return false; if (WebInputEvent::isGestureEventType(inputEvent.type) && inputEvent.type == WebInputEvent::GestureTap) { // Only let GestureTab in (we only need it and we know PlatformGestureEventBuilder supports it). PlatformGestureEvent gestureEvent = PlatformGestureEventBuilder(page->deprecatedLocalMainFrame()->view(), static_cast<const WebGestureEvent&>(inputEvent)); return ic->handleGestureEvent(toLocalFrame(page->mainFrame()), gestureEvent); } if (WebInputEvent::isMouseEventType(inputEvent.type) && inputEvent.type != WebInputEvent::MouseEnter) { // PlatformMouseEventBuilder does not work with MouseEnter type, so we filter it out manually. PlatformMouseEvent mouseEvent = PlatformMouseEventBuilder(page->deprecatedLocalMainFrame()->view(), static_cast<const WebMouseEvent&>(inputEvent)); return ic->handleMouseEvent(toLocalFrame(page->mainFrame()), mouseEvent); } if (WebInputEvent::isTouchEventType(inputEvent.type)) { PlatformTouchEvent touchEvent = PlatformTouchEventBuilder(page->deprecatedLocalMainFrame()->view(), static_cast<const WebTouchEvent&>(inputEvent)); return ic->handleTouchEvent(toLocalFrame(page->mainFrame()), touchEvent); } if (WebInputEvent::isKeyboardEventType(inputEvent.type)) { PlatformKeyboardEvent keyboardEvent = PlatformKeyboardEventBuilder(static_cast<const WebKeyboardEvent&>(inputEvent)); return ic->handleKeyboardEvent(page->deprecatedLocalMainFrame(), keyboardEvent); } return false; }
bool WebPagePopupImpl::handleGestureEvent(const WebGestureEvent& event) { if (m_closing || !m_page || !m_page->mainFrame() || !toLocalFrame(m_page->mainFrame())->view()) return false; if (event.type == WebInputEvent::GestureTap && !isGestureEventInWindow(event)) { cancel(); return false; } LocalFrame& frame = *toLocalFrame(m_page->mainFrame()); return frame.eventHandler().handleGestureEvent(PlatformGestureEventBuilder(frame.view(), event)); }
void Page::setTimerAlignmentInterval(double interval) { if (interval == m_timerAlignmentInterval) return; m_timerAlignmentInterval = interval; for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNextWithWrap(false)) { if (frame->isLocalFrame() && toLocalFrame(frame)->document()) toLocalFrame(frame)->document()->didChangeTimerAlignmentInterval(); } }
static LocalFrame* findFrameWithSecurityOrigin(LocalFrame* inspectedFrame, const String& originRawString) { for (Frame* frame = inspectedFrame; frame; frame = frame->tree().traverseNext(inspectedFrame)) { if (!frame->isLocalFrame()) continue; RefPtr<SecurityOrigin> documentOrigin = toLocalFrame(frame)->document()->securityOrigin(); if (documentOrigin->toRawString() == originRawString) return toLocalFrame(frame); } return nullptr; }
Frame* FrameTree::find(const AtomicString& name) const { if (name == "_self" || name == "_current" || name.isEmpty()) return m_thisFrame; if (name == "_top") { for (LocalFrame* f = toLocalFrame(m_thisFrame); f; f = toLocalFrame(f->tree().parent())) { if (f->isNwFakeTop()) return f; } return top(); } if (name == "_parent") { if (m_thisFrame->isNwFakeTop()) return m_thisFrame.get(); return parent() ? parent() : m_thisFrame.get(); } // Since "_blank" should never be any frame's name, the following just amounts to an optimization. if (name == "_blank") return nullptr; // Search subtree starting with this frame first. for (Frame* frame = m_thisFrame; frame; frame = frame->tree().traverseNext(m_thisFrame)) if (frame->tree().name() == name) return frame; // Search the entire tree for this page next. Page* page = m_thisFrame->page(); // The frame could have been detached from the page, so check it. if (!page) return nullptr; for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) if (frame->tree().name() == name) return frame; // Search the entire tree of each of the other pages in this namespace. // FIXME: Is random order OK? const HashSet<Page*>& pages = Page::ordinaryPages(); for (const Page* otherPage : pages) { if (otherPage != page) { for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree().traverseNext()) { if (frame->tree().name() == name) return frame; } } } return nullptr; }
LocalFrame* InspectorPageAgent::findFrameWithSecurityOrigin(const String& originRawString) { for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) { // FIXME: RemoteFrame security origins are not yet available. if (!frame->isLocalFrame()) continue; RefPtr<SecurityOrigin> documentOrigin = toLocalFrame(frame)->document()->securityOrigin(); if (documentOrigin->toRawString() == originRawString) return toLocalFrame(frame); } return 0; }
void WindowProxy::createContext() { // FIXME: This should be a null check of m_frame->client(), but there are // still some edge cases // that this fails to catch during frame detach. if (m_frame->isLocalFrame() && !toLocalFrame(m_frame)->loader().documentLoader()) return; // Create a new v8::Context with the window object as the global object // (aka the inner global). Reuse the global proxy object (aka the outer // global) if it already exists. See the comments in // setupWindowPrototypeChain for the structure of the prototype chain of // the global object. v8::Local<v8::ObjectTemplate> globalTemplate = V8Window::domTemplate(m_isolate, *m_world)->InstanceTemplate(); if (globalTemplate.IsEmpty()) return; // FIXME: It's not clear what the right thing to do for remote frames is. // The extensions registered don't generally seem to make sense for remote // frames, so skip it for now. Vector<const char*> extensionNames; if (m_frame->isLocalFrame()) { LocalFrame* frame = toLocalFrame(m_frame); // Dynamically tell v8 about our extensions now. const V8Extensions& extensions = ScriptController::registeredExtensions(); extensionNames.reserveInitialCapacity(extensions.size()); int extensionGroup = m_world->extensionGroup(); int worldId = m_world->worldId(); for (const auto* extension : extensions) { if (!frame->loader().client()->allowScriptExtension( extension->name(), extensionGroup, worldId)) continue; extensionNames.append(extension->name()); } } v8::ExtensionConfiguration extensionConfiguration(extensionNames.size(), extensionNames.data()); v8::Local<v8::Context> context; { V8PerIsolateData::UseCounterDisabledScope useCounterDisabled( V8PerIsolateData::from(m_isolate)); context = v8::Context::New(m_isolate, &extensionConfiguration, globalTemplate, m_global.newLocal(m_isolate)); } if (context.IsEmpty()) return; m_scriptState = ScriptState::create(context, m_world); }
Frame* FrameTree::scopedChild(const AtomicString& name) const { if (!m_thisFrame->isLocalFrame()) return 0; TreeScope* scope = toLocalFrame(m_thisFrame)->document(); if (!scope) return 0; for (Frame* child = firstChild(); child; child = child->tree().nextSibling()) if (child->tree().name() == name && child->isLocalFrame() && toLocalFrame(child)->inScope(scope)) return child; return 0; }
WebInputEventResult WebPagePopupImpl::handleGestureEvent( const WebGestureEvent& event) { if (m_closing || !m_page || !m_page->mainFrame() || !toLocalFrame(m_page->mainFrame())->view()) return WebInputEventResult::NotHandled; if ((event.type == WebInputEvent::GestureTap || event.type == WebInputEvent::GestureTapDown) && !isViewportPointInWindow(event.x, event.y)) { cancel(); return WebInputEventResult::NotHandled; } LocalFrame& frame = *toLocalFrame(m_page->mainFrame()); return frame.eventHandler().handleGestureEvent( PlatformGestureEventBuilder(frame.view(), event)); }
void Page::setNeedsRecalcStyleInAllFrames() { for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) { if (frame->isLocalFrame()) toLocalFrame(frame)->document()->styleResolverChanged(); } }
void InspectorPageAgent::frameAttachedToParent(LocalFrame* frame) { Frame* parentFrame = frame->tree().parent(); if (!parentFrame->isLocalFrame()) parentFrame = 0; m_frontend->frameAttached(frameId(frame), frameId(toLocalFrame(parentFrame))); }
void ScreenOrientationController::notifyOrientationChanged() { ASSERT(RuntimeEnabledFeatures::screenOrientationEnabled()); if (!isActiveAndVisible()) return; updateOrientation(); // Keep track of the frames that need to be notified before notifying the // current frame as it will prevent side effects from the change event // handlers. WillBeHeapVector<RefPtrWillBeMember<LocalFrame> > childFrames; for (Frame* child = frame()->tree().firstChild(); child; child = child->tree().nextSibling()) { if (child->isLocalFrame()) childFrames.append(toLocalFrame(child)); } // Notify current orientation object. if (!m_dispatchEventTimer.isActive()) m_dispatchEventTimer.startOneShot(0, FROM_HERE); // ... and child frames, if they have a ScreenOrientationController. for (size_t i = 0; i < childFrames.size(); ++i) { if (ScreenOrientationController* controller = ScreenOrientationController::from(*childFrames[i])) controller->notifyOrientationChanged(); } }
void WindowProxy::updateDocumentProperty() { if (!m_world->isMainWorld()) return; if (m_frame->isRemoteFrame()) { return; } ScriptState::Scope scope(m_scriptState.get()); v8::Local<v8::Context> context = m_scriptState->context(); LocalFrame* frame = toLocalFrame(m_frame); v8::Local<v8::Value> documentWrapper = toV8(frame->document(), context->Global(), context->GetIsolate()); if (documentWrapper.IsEmpty()) return; ASSERT(documentWrapper == m_document.newLocal(m_isolate) || m_document.isEmpty()); if (m_document.isEmpty()) updateDocumentWrapper(v8::Local<v8::Object>::Cast(documentWrapper)); checkDocumentWrapper(m_document.newLocal(m_isolate), frame->document()); ASSERT(documentWrapper->IsObject()); // TODO(bashi): Avoid using ForceSet(). When we use accessors to implement // attributes, we may be able to remove updateDocumentProperty(). if (!v8CallBoolean(context->Global()->ForceSet(context, v8AtomicString(m_isolate, "document"), documentWrapper, static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete)))) return; // We also stash a reference to the document on the inner global object so that // LocalDOMWindow objects we obtain from JavaScript references are guaranteed to have // live Document objects. V8HiddenValue::setHiddenValue(m_isolate, toInnerGlobalObject(context), V8HiddenValue::document(m_isolate), documentWrapper); }
void WindowProxy::disposeContext(GlobalDetachmentBehavior behavior) { if (!isContextInitialized()) return; v8::HandleScope handleScope(m_isolate); v8::Local<v8::Context> context = m_scriptState->context(); if (m_frame->isLocalFrame()) { LocalFrame* frame = toLocalFrame(m_frame); // The embedder could run arbitrary code in response to the willReleaseScriptContext callback, so all disposing should happen after it returns. frame->loader().client()->willReleaseScriptContext(context, m_world->worldId()); InspectorInstrumentation::willReleaseScriptContext(frame, m_scriptState.get()); } m_document.clear(); if (behavior == DetachGlobal) m_scriptState->detachGlobalObject(); m_scriptState->disposePerContextData(); // It's likely that disposing the context has created a lot of // garbage. Notify V8 about this so it'll have a chance of cleaning // it up when idle. V8GCForContextDispose::instance().notifyContextDisposed(m_frame->isMainFrame()); }
IntersectionObserver* IntersectionObserver::create(const IntersectionObserverInit& observerInit, IntersectionObserverCallback& callback, ExceptionState& exceptionState) { RefPtrWillBeRawPtr<Node> root = observerInit.root(); if (!root) { // TODO(szager): Use Document instead of document element for implicit root. (crbug.com/570538) ExecutionContext* context = callback.executionContext(); ASSERT(context->isDocument()); Frame* mainFrame = toDocument(context)->frame()->tree().top(); if (mainFrame && mainFrame->isLocalFrame()) root = toLocalFrame(mainFrame)->document(); } if (!root) { exceptionState.throwDOMException(HierarchyRequestError, "Unable to get root node in main frame to track."); return nullptr; } Vector<Length> rootMargin; if (observerInit.hasRootMargin()) parseRootMargin(observerInit.rootMargin(), rootMargin, exceptionState); if (exceptionState.hadException()) return nullptr; Vector<float> thresholds; if (observerInit.hasThreshold()) parseThresholds(observerInit.threshold(), thresholds, exceptionState); else thresholds.append(0); if (exceptionState.hadException()) return nullptr; return new IntersectionObserver(callback, *root, rootMargin, thresholds); }
void WindowProxy::updateDocumentProperty() { if (!m_world->isMainWorld()) return; if (m_frame->isRemoteFrame()) { return; } ScriptState::Scope scope(m_scriptState.get()); v8::Local<v8::Context> context = m_scriptState->context(); LocalFrame* frame = toLocalFrame(m_frame); v8::Local<v8::Value> documentWrapper = toV8(frame->document(), context->Global(), context->GetIsolate()); if (documentWrapper.IsEmpty()) return; ASSERT(documentWrapper == m_document.newLocal(m_isolate) || m_document.isEmpty()); if (m_document.isEmpty()) updateDocumentWrapper(v8::Local<v8::Object>::Cast(documentWrapper)); checkDocumentWrapper(m_document.newLocal(m_isolate), frame->document()); ASSERT(documentWrapper->IsObject()); // TODO(jochen): Don't replace the accessor with a data value. We need a way to tell v8 that the accessor's return value won't change after this point. if (!v8CallBoolean(context->Global()->ForceSet(context, v8AtomicString(m_isolate, "document"), documentWrapper, static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete)))) return; }
void BeaconLoader::willSendRequest(WebURLLoader*, WebURLRequest& passedNewRequest, const WebURLResponse& passedRedirectResponse) { passedNewRequest.setAllowStoredCredentials(true); ResourceRequest& newRequest(passedNewRequest.toMutableResourceRequest()); const ResourceResponse& redirectResponse(passedRedirectResponse.toResourceResponse()); ASSERT(!newRequest.isNull()); ASSERT(!redirectResponse.isNull()); String errorDescription; StoredCredentials withCredentials = AllowStoredCredentials; ResourceLoaderOptions options; if (!CrossOriginAccessControl::handleRedirect(m_beaconOrigin.get(), newRequest, redirectResponse, withCredentials, options, errorDescription)) { if (page() && page()->mainFrame()) { if (page()->mainFrame()->isLocalFrame()) { LocalFrame* localFrame = toLocalFrame(page()->mainFrame()); if (localFrame->document()) localFrame->document()->addConsoleMessage(ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorDescription)); } } // Cancel the load and self destruct. dispose(); return; } // FIXME: http://crbug.com/427429 is needed to correctly propagate // updates of Origin: following this successful redirect. }
bool SpellCheckerClientImpl::shouldSpellcheckByDefault() { // Spellcheck should be enabled for all editable areas (such as textareas, // contentEditable regions, designMode docs and inputs). if (!m_webView->focusedCoreFrame()->isLocalFrame()) return false; const LocalFrame* frame = toLocalFrame(m_webView->focusedCoreFrame()); if (!frame) return false; if (frame->spellChecker().isSpellCheckingEnabledInFocusedNode()) return true; const Document* document = frame->document(); if (!document) return false; const Element* element = document->focusedElement(); // If |element| is null, we default to allowing spellchecking. This is done // in order to mitigate the issue when the user clicks outside the textbox, // as a result of which |element| becomes null, resulting in all the spell // check markers being deleted. Also, the LocalFrame will decide not to do // spellchecking if the user can't edit - so returning true here will not // cause any problems to the LocalFrame's behavior. if (!element) return true; const LayoutObject* layoutObject = element->layoutObject(); if (!layoutObject) return false; return true; }
void MixedContentChecker::handleCertificateError(LocalFrame* frame, const ResourceResponse& response, WebURLRequest::FrameType frameType, WebURLRequest::RequestContext requestContext) { Frame* effectiveFrame = effectiveFrameForFrameType(frame, frameType); if (frameType == WebURLRequest::FrameTypeTopLevel || !effectiveFrame) return; // TODO(estark): handle remote frames, perhaps by omitting security info when the effective frame is remote. if (!effectiveFrame->isLocalFrame()) return; LocalFrame* localEffectiveFrame = toLocalFrame(effectiveFrame); // Use the current local frame's client; the embedder doesn't // distinguish mixed content signals from different frames on the // same page. FrameLoaderClient* client = frame->loader().client(); ContextType contextType = MixedContentChecker::contextTypeFromContext(requestContext, effectiveFrame); if (contextType == ContextTypeBlockable) { client->didRunContentWithCertificateErrors(response.url(), response.getSecurityInfo(), mainResourceUrlForFrame(effectiveFrame), localEffectiveFrame->loader().documentLoader()->response().getSecurityInfo()); } else { // contextTypeFromContext() never returns NotMixedContent (it // computes the type of mixed content, given that the content is // mixed). ASSERT(contextType != ContextTypeNotMixedContent); client->didDisplayContentWithCertificateErrors(response.url(), response.getSecurityInfo(), mainResourceUrlForFrame(effectiveFrame), localEffectiveFrame->loader().documentLoader()->response().getSecurityInfo()); } }
void PageAnimator::serviceScriptedAnimations(double monotonicAnimationStartTime) { m_animationFramePending = false; TemporaryChange<bool> servicing(m_servicingAnimations, true); WillBeHeapVector<RefPtrWillBeMember<Document> > documents; for (RefPtr<Frame> frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) { if (frame->isLocalFrame()) documents.append(toLocalFrame(frame.get())->document()); } for (size_t i = 0; i < documents.size(); ++i) { if (documents[i]->frame()) { documents[i]->view()->serviceScrollAnimations(); if (const FrameView::ScrollableAreaSet* scrollableAreas = documents[i]->view()->scrollableAreas()) { for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != scrollableAreas->end(); ++it) (*it)->serviceScrollAnimations(); } } } for (size_t i = 0; i < documents.size(); ++i) { DocumentAnimations::updateAnimationTimingForAnimationFrame(*documents[i], monotonicAnimationStartTime); SVGDocumentExtensions::serviceOnAnimationFrame(*documents[i], monotonicAnimationStartTime); } for (size_t i = 0; i < documents.size(); ++i) documents[i]->serviceScriptedAnimations(monotonicAnimationStartTime); }
bool SVGImage::currentFrameHasSingleSecurityOrigin() const { if (!m_page) return true; LocalFrame* frame = toLocalFrame(m_page->mainFrame()); RELEASE_ASSERT(frame->document()->loadEventFinished()); SVGSVGElement* rootElement = frame->document()->accessSVGExtensions().rootElement(); if (!rootElement) return true; // Don't allow foreignObject elements or images that are not known to be // single-origin since these can leak cross-origin information. for (Node* node = rootElement; node; node = ComposedTreeTraversal::next(*node)) { if (isSVGForeignObjectElement(*node)) return false; if (isSVGImageElement(*node)) { if (!toSVGImageElement(*node).currentFrameHasSingleSecurityOrigin()) return false; } else if (isSVGFEImageElement(*node)) { if (!toSVGFEImageElement(*node).currentFrameHasSingleSecurityOrigin()) return false; } } // Because SVG image rendering disallows external resources and links, these // images effectively are restricted to a single security origin. return true; }
inline void TextResourceDecoderBuilder::setupEncoding(TextResourceDecoder* decoder, Document* document) { LocalFrame* frame = document->frame(); LocalFrame* parentFrame = 0; if (frame && frame->tree().parent() && frame->tree().parent()->isLocalFrame()) parentFrame = toLocalFrame(frame->tree().parent()); if (!m_encoding.isEmpty()) decoder->setEncoding(m_encoding.string(), m_encodingWasChosenByUser ? TextResourceDecoder::UserChosenEncoding : TextResourceDecoder::EncodingFromHTTPHeader); // Set the hint encoding to the parent frame encoding only if // the parent and the current frames share the security origin. // We impose this condition because somebody can make a child frameg63 // containing a carefully crafted html/javascript in one encoding // that can be mistaken for hintEncoding (or related encoding) by // an auto detector. When interpreted in the latter, it could be // an attack vector. // FIXME: This might be too cautious for non-7bit-encodings and // we may consider relaxing this later after testing. if (frame && canReferToParentFrameEncoding(frame, parentFrame)) { if (parentFrame->document()->encodingWasDetectedHeuristically()) decoder->setHintEncoding(parentFrame->document()->encoding()); if (m_encoding.isEmpty()) decoder->setEncoding(parentFrame->document()->inputEncoding().string(), TextResourceDecoder::EncodingFromParentFrame); } }
ScopedPageLoadDeferrer::ScopedPageLoadDeferrer(Page* exclusion) { const HashSet<Page*>& pages = Page::ordinaryPages(); HashSet<Page*>::const_iterator end = pages.end(); for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) { Page* page = *it; if (page == exclusion || page->defersLoading()) continue; if (page->mainFrame()->isLocalFrame()) { m_deferredFrames.append(page->deprecatedLocalMainFrame()); // Ensure that we notify the client if the initial empty document is accessed before // showing anything modal, to prevent spoofs while the modal window or sheet is visible. page->deprecatedLocalMainFrame()->loader().notifyIfInitialDocumentAccessed(); } // This code is not logically part of load deferring, but we do not want JS code executed // beneath modal windows or sheets, which is exactly when ScopedPageLoadDeferrer is used. for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) { if (frame->isLocalFrame()) toLocalFrame(frame)->document()->suspendScheduledTasks(); } } size_t count = m_deferredFrames.size(); for (size_t i = 0; i < count; ++i) { if (Page* page = m_deferredFrames[i]->page()) page->setDefersLoading(true); } }