DocumentWriter* DocumentLoader::createWriterFor(const DocumentInit& init, const AtomicString& mimeType, const AtomicString& encoding, bool dispatchWindowObjectAvailable, ParserSynchronizationPolicy parsingPolicy, const KURL& overridingURL) { LocalFrame* frame = init.frame(); ASSERT(!frame->document() || !frame->document()->isActive()); ASSERT(frame->tree().childCount() == 0); if (!init.shouldReuseDefaultView()) frame->setDOMWindow(LocalDOMWindow::create(*frame)); Document* document = frame->localDOMWindow()->installNewDocument(mimeType, init); // This should be set before receivedFirstData(). if (!overridingURL.isEmpty()) frame->document()->setBaseURLOverride(overridingURL); frame->loader().didInstallNewDocument(dispatchWindowObjectAvailable); // This must be called before DocumentWriter is created, otherwise HTML parser // will use stale values from HTMLParserOption. if (!dispatchWindowObjectAvailable) frame->loader().receivedFirstData(); frame->loader().didBeginDocument(); return DocumentWriter::create(document, parsingPolicy, mimeType, encoding); }
void InspectorPageAgent::navigate(ErrorString*, const String& url) { UserGestureIndicator indicator(DefinitelyProcessingNewUserGesture); LocalFrame* frame = m_page->mainFrame(); FrameLoadRequest request(frame->document(), ResourceRequest(frame->document()->completeURL(url))); frame->loader().load(request); }
void createWindowForRequest(const FrameLoadRequest& request, LocalFrame& openerFrame, NavigationPolicy policy, ShouldSendReferrer shouldSendReferrer) { if (openerFrame.document()->pageDismissalEventBeingDispatched() != Document::NoDismissal) return; if (openerFrame.document() && openerFrame.document()->isSandboxed(SandboxPopups)) return; if (!DOMWindow::allowPopUp(openerFrame)) return; if (policy == NavigationPolicyCurrentTab) policy = NavigationPolicyNewForegroundTab; WindowFeatures features; bool created; LocalFrame* newFrame = createWindow(openerFrame, openerFrame, request, features, policy, shouldSendReferrer, created); if (!newFrame) return; if (shouldSendReferrer == MaybeSendReferrer) { newFrame->loader().setOpener(&openerFrame); newFrame->document()->setReferrerPolicy(openerFrame.document()->referrerPolicy()); } FrameLoadRequest newRequest(0, request.resourceRequest()); newRequest.setFormState(request.formState()); newFrame->loader().load(newRequest); }
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; // 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_scriptState.get(), v8::Local<v8::Object>::Cast(context->Global()->GetPrototype()), V8HiddenValue::document(m_isolate), documentWrapper); }
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 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. }
MediaValuesCached::MediaValuesCachedData::MediaValuesCachedData( Document& document) : MediaValuesCached::MediaValuesCachedData() { ASSERT(isMainThread()); LocalFrame* frame = MediaValues::frameFrom(document); // TODO(hiroshige): Clean up |frame->view()| conditions. ASSERT(!frame || frame->view()); if (frame && frame->view()) { ASSERT(frame->document() && !frame->document()->layoutViewItem().isNull()); // In case that frame is missing (e.g. for images that their document does // not have a frame) // We simply leave the MediaValues object with the default // MediaValuesCachedData values. viewportWidth = MediaValues::calculateViewportWidth(frame); viewportHeight = MediaValues::calculateViewportHeight(frame); deviceWidth = MediaValues::calculateDeviceWidth(frame); deviceHeight = MediaValues::calculateDeviceHeight(frame); devicePixelRatio = MediaValues::calculateDevicePixelRatio(frame); colorBitsPerComponent = MediaValues::calculateColorBitsPerComponent(frame); monochromeBitsPerComponent = MediaValues::calculateMonochromeBitsPerComponent(frame); primaryPointerType = MediaValues::calculatePrimaryPointerType(frame); availablePointerTypes = MediaValues::calculateAvailablePointerTypes(frame); primaryHoverType = MediaValues::calculatePrimaryHoverType(frame); availableHoverTypes = MediaValues::calculateAvailableHoverTypes(frame); defaultFontSize = MediaValues::calculateDefaultFontSize(frame); threeDEnabled = MediaValues::calculateThreeDEnabled(frame); strictMode = MediaValues::calculateStrictMode(frame); displayMode = MediaValues::calculateDisplayMode(frame); mediaType = MediaValues::calculateMediaType(frame); displayShape = MediaValues::calculateDisplayShape(frame); } }
StorageArea* InspectorDOMStorageAgent::findStorageArea(ErrorString* errorString, const RefPtr<JSONObject>& storageId, LocalFrame*& targetFrame) { String securityOrigin; bool isLocalStorage = false; bool success = storageId->getString("securityOrigin", &securityOrigin); if (success) success = storageId->getBoolean("isLocalStorage", &isLocalStorage); if (!success) { if (errorString) *errorString = "Invalid storageId format"; return nullptr; } if (!m_page->mainFrame()->isLocalFrame()) return nullptr; LocalFrame* frame = InspectedFrames(m_page->deprecatedLocalMainFrame()).frameWithSecurityOrigin(securityOrigin); if (!frame) { if (errorString) *errorString = "LocalFrame not found for the given security origin"; return nullptr; } targetFrame = frame; if (isLocalStorage) return StorageNamespace::localStorageArea(frame->document()->securityOrigin()); return StorageNamespaceController::from(m_page)->sessionStorage()->storageArea(frame->document()->securityOrigin()); }
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 = frame ? frame->tree().parent() : 0; 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); } }
// static bool MixedContentChecker::shouldBlockWebSocket(LocalFrame* frame, const KURL& url, MixedContentChecker::ReportingStatus reportingStatus) { LocalFrame* mixedFrame = inWhichFrameIsContentMixed(frame, WebURLRequest::FrameTypeNone, url); if (!mixedFrame) return false; UseCounter::count(mixedFrame, UseCounter::MixedContentPresent); UseCounter::count(mixedFrame, UseCounter::MixedContentWebSocket); Settings* settings = mixedFrame->settings(); FrameLoaderClient* client = mixedFrame->loader().client(); SecurityOrigin* securityOrigin = mixedFrame->document()->securityOrigin(); bool allowed = false; // If we're in strict mode, we'll automagically fail everything, and intentionally skip // the client checks in order to prevent degrading the site's security UI. bool strictMode = mixedFrame->document()->shouldEnforceStrictMixedContentChecking() || settings->strictMixedContentChecking(); if (!strictMode) { bool allowedPerSettings = settings && settings->allowRunningOfInsecureContent(); allowed = client->allowRunningInsecureContent(allowedPerSettings, securityOrigin, url); } if (allowed) client->didRunInsecureContent(securityOrigin, url); if (reportingStatus == SendReport) logToConsoleAboutWebSocket(frame, url, allowed); return !allowed; }
PassOwnPtrWillBeRawPtr<StorageArea> InspectorDOMStorageAgent::findStorageArea(ErrorString* errorString, const RefPtr<JSONObject>& storageId, LocalFrame*& targetFrame) { String securityOrigin; bool isLocalStorage = false; bool success = storageId->getString("securityOrigin", &securityOrigin); if (success) success = storageId->getBoolean("isLocalStorage", &isLocalStorage); if (!success) { if (errorString) *errorString = "Invalid storageId format"; return nullptr; } LocalFrame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin); if (!frame) { if (errorString) *errorString = "LocalFrame not found for the given security origin"; return nullptr; } targetFrame = frame; if (isLocalStorage) return StorageNamespace::localStorageArea(frame->document()->securityOrigin()); return m_pageAgent->page()->sessionStorage()->storageArea(frame->document()->securityOrigin()); }
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 Page::setTimerAlignmentInterval(double interval) { if (interval == m_timerAlignmentInterval) return; m_timerAlignmentInterval = interval; LocalFrame* frame = mainFrame(); if (frame->document()) frame->document()->didChangeTimerAlignmentInterval(); }
bool SVGImage::hasAnimations() const { if (!m_page) return false; LocalFrame* frame = m_page->mainFrame(); SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement(); if (!rootElement) return false; return rootElement->timeContainer()->hasAnimations() || frame->document()->timeline().hasPendingUpdates(); }
DOMWindow* createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures& windowFeatures, LocalDOMWindow& callingWindow, LocalFrame& firstFrame, LocalFrame& openerFrame) { LocalFrame* activeFrame = callingWindow.frame(); ASSERT(activeFrame); KURL completedURL = urlString.isEmpty() ? KURL(ParsedURLString, emptyString()) : firstFrame.document()->completeURL(urlString); if (!completedURL.isEmpty() && !completedURL.isValid()) { // Don't expose client code to invalid URLs. callingWindow.printErrorMessage("Unable to open a window with invalid URL '" + completedURL.getString() + "'.\n"); return nullptr; } FrameLoadRequest frameRequest(callingWindow.document(), completedURL, frameName); frameRequest.setShouldSetOpener(windowFeatures.noopener ? NeverSetOpener : MaybeSetOpener); frameRequest.resourceRequest().setFrameType(WebURLRequest::FrameTypeAuxiliary); frameRequest.resourceRequest().setRequestorOrigin(SecurityOrigin::create(activeFrame->document()->url())); // Normally, FrameLoader would take care of setting the referrer for a navigation that is // triggered from javascript. However, creating a window goes through sufficient processing // that it eventually enters FrameLoader as an embedder-initiated navigation. FrameLoader // assumes no responsibility for generating an embedder-initiated navigation's referrer, // so we need to ensure the proper referrer is set now. frameRequest.resourceRequest().setHTTPReferrer(SecurityPolicy::generateReferrer(activeFrame->document()->getReferrerPolicy(), completedURL, activeFrame->document()->outgoingReferrer())); // Records HasUserGesture before the value is invalidated inside createWindow(LocalFrame& openerFrame, ...). // This value will be set in ResourceRequest loaded in a new LocalFrame. bool hasUserGesture = UserGestureIndicator::processingUserGesture(); // We pass the opener frame for the lookupFrame in case the active frame is different from // the opener frame, and the name references a frame relative to the opener frame. bool created; Frame* newFrame = createWindowHelper(openerFrame, *activeFrame, openerFrame, frameRequest, windowFeatures, NavigationPolicyIgnore, created); if (!newFrame) return nullptr; if (newFrame->domWindow()->isInsecureScriptAccess(callingWindow, completedURL)) return newFrame->domWindow(); // TODO(dcheng): Special case for window.open("about:blank") to ensure it loads synchronously into // a new window. This is our historical behavior, and it's consistent with the creation of // a new iframe with src="about:blank". Perhaps we could get rid of this if we started reporting // the initial empty document's url as about:blank? See crbug.com/471239. // TODO(japhet): This special case is also necessary for behavior asserted by some extensions tests. // Using NavigationScheduler::scheduleNavigationChange causes the navigation to be flagged as a // client redirect, which is observable via the webNavigation extension api. if (created) { FrameLoadRequest request(callingWindow.document(), completedURL); request.resourceRequest().setHasUserGesture(hasUserGesture); newFrame->navigate(request); } else if (!urlString.isEmpty()) { newFrame->navigate(*callingWindow.document(), completedURL, false, hasUserGesture ? UserGestureStatus::Active : UserGestureStatus::None); } return newFrame->domWindow(); }
void ApplicationCacheHost::selectCacheWithManifest(const KURL& manifestURL) { if (m_host && !m_host->selectCacheWithManifest(manifestURL)) { // It's a foreign entry, restart the current navigation from the top // of the navigation algorithm. The navigation will not result in the // same resource being loaded, because "foreign" entries are never picked // during navigation. // see ApplicationCacheGroup::selectCache() LocalFrame* frame = m_documentLoader->frame(); frame->navigationScheduler().scheduleLocationChange(frame->document(), frame->document()->url()); } }
ExecutionContext* InspectorFileSystemAgent::assertExecutionContextForOrigin(ErrorString* error, SecurityOrigin* origin) { for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) { if (!frame->isLocalFrame()) continue; LocalFrame* localFrame = toLocalFrame(frame); if (localFrame->document() && localFrame->document()->securityOrigin()->isSameSchemeHostPort(origin)) return localFrame->document(); } *error = "No frame is available for the request"; return 0; }
bool TextFinder::shouldScopeMatches(const String& searchText, const WebFindOptions& options) { // Don't scope if we can't find a frame or a view. // The user may have closed the tab/application, so abort. LocalFrame* frame = ownerFrame().frame(); if (!frame || !frame->view() || !frame->page()) return false; DCHECK(frame->document()); DCHECK(frame->view()); if (options.force) return true; if (!ownerFrame().hasVisibleContent()) return false; // If the frame completed the scoping operation and found 0 matches the last // time it was searched, then we don't have to search it again if the user is // just adding to the search string or sending the same search string again. if (m_lastFindRequestCompletedWithNoMatches && !m_lastSearchString.isEmpty()) { // Check to see if the search string prefixes match. String previousSearchPrefix = searchText.substring(0, m_lastSearchString.length()); if (previousSearchPrefix == m_lastSearchString) return false; // Don't search this frame, it will be fruitless. } return true; }
bool MixedContentChecker::isMixedFormAction(LocalFrame* frame, const KURL& url, ReportingStatus reportingStatus) { // For whatever reason, some folks handle forms via JavaScript, and submit to `javascript:void(0)` // rather than calling `preventDefault()`. We special-case `javascript:` URLs here, as they don't // introduce MixedContent for form submissions. if (url.protocolIs("javascript")) return false; LocalFrame* mixedFrame = inWhichFrameIsContentMixed(frame, WebURLRequest::FrameTypeNone, url); if (!mixedFrame) return false; UseCounter::count(mixedFrame, UseCounter::MixedContentPresent); mixedFrame->loader().client()->didDisplayInsecureContent(); if (reportingStatus == SendReport) { String message = String::format( "Mixed Content: The page at '%s' was loaded over a secure connection, but contains a form which targets an insecure endpoint '%s'. This endpoint should be made available over a secure connection.", frame->document()->url().elidedString().utf8().data(), url.elidedString().utf8().data()); mixedFrame->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessageSource, WarningMessageLevel, message)); } return true; }
v8::Local<v8::Value> V8EventListener::callListenerFunction( ScriptState* scriptState, v8::Local<v8::Value> jsEvent, Event* event) { ASSERT(!jsEvent.IsEmpty()); v8::Local<v8::Function> handlerFunction = getListenerFunction(scriptState); v8::Local<v8::Object> receiver = getReceiverObject(scriptState, event); if (handlerFunction.IsEmpty() || receiver.IsEmpty()) return v8::Local<v8::Value>(); if (!scriptState->getExecutionContext()->isDocument()) return v8::Local<v8::Value>(); LocalFrame* frame = toDocument(scriptState->getExecutionContext())->frame(); if (!frame) return v8::Local<v8::Value>(); // TODO(jochen): Consider moving this check into canExecuteScripts. // http://crbug.com/608641 if (scriptState->world().isMainWorld() && !frame->script().canExecuteScripts(AboutToExecuteScript)) return v8::Local<v8::Value>(); v8::Local<v8::Value> parameters[1] = {jsEvent}; v8::Local<v8::Value> result; if (!V8ScriptRunner::callFunction(handlerFunction, frame->document(), receiver, WTF_ARRAY_LENGTH(parameters), parameters, scriptState->isolate()) .ToLocal(&result)) return v8::Local<v8::Value>(); return result; }
// static LocalFrame* MixedContentChecker::inWhichFrameIsContentMixed(LocalFrame* frame, WebURLRequest::FrameType frameType, const KURL& url) { // We only care about subresource loads; top-level navigations cannot be mixed content. Neither can frameless requests. if (frameType == WebURLRequest::FrameTypeTopLevel || !frame) return nullptr; // Check the top frame first. if (Frame* top = frame->tree().top()) { // FIXME: We need a way to access the top-level frame's SecurityOrigin when that frame // is in a different process from the current frame. Until that is done, we bail out. if (!top->isLocalFrame()) return nullptr; LocalFrame* localTop = toLocalFrame(top); measureStricterVersionOfIsMixedContent(localTop, url); if (isMixedContent(localTop->document()->securityOrigin(), url)) return localTop; } measureStricterVersionOfIsMixedContent(frame, url); if (isMixedContent(frame->document()->securityOrigin(), url)) return frame; // No mixed content, no problem. return nullptr; }
void StorageArea::dispatchSessionStorageEvent( const String& key, const String& oldValue, const String& newValue, SecurityOrigin* securityOrigin, const KURL& pageURL, const WebStorageNamespace& sessionNamespace, WebStorageArea* sourceAreaInstance) { Page* page = findPageWithSessionStorageNamespace(sessionNamespace); if (!page) return; for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) { // FIXME: We do not yet have a way to dispatch events to out-of-process // frames. if (!frame->isLocalFrame()) continue; LocalFrame* localFrame = toLocalFrame(frame); LocalDOMWindow* localWindow = localFrame->domWindow(); Storage* storage = DOMWindowStorage::from(*localWindow).optionalSessionStorage(); if (storage && localFrame->document()->getSecurityOrigin()->canAccess( securityOrigin) && !isEventSource(storage, sourceAreaInstance)) localFrame->domWindow()->enqueueWindowEvent(StorageEvent::create( EventTypeNames::storage, key, oldValue, newValue, pageURL, storage)); } if (InspectorDOMStorageAgent* agent = StorageNamespaceController::from(page)->inspectorAgent()) agent->didDispatchDOMStorageEvent(key, oldValue, newValue, SessionStorage, securityOrigin); }
IntSize SVGImage::containerSize() const { if (!m_page) return IntSize(); LocalFrame* frame = m_page->mainFrame(); SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement(); if (!rootElement) return IntSize(); RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer()); if (!renderer) return IntSize(); // If a container size is available it has precedence. IntSize containerSize = renderer->containerSize(); if (!containerSize.isEmpty()) return containerSize; // Assure that a container size is always given for a non-identity zoom level. ASSERT(renderer->style()->effectiveZoom() == 1); FloatSize currentSize; if (rootElement->intrinsicWidth().isFixed() && rootElement->intrinsicHeight().isFixed()) currentSize = rootElement->currentViewportSize(); else currentSize = rootElement->currentViewBoxRect().size(); if (!currentSize.isEmpty()) return IntSize(static_cast<int>(ceilf(currentSize.width())), static_cast<int>(ceilf(currentSize.height()))); // As last resort, use CSS default intrinsic size. return IntSize(300, 150); }
static SVGSVGElement* svgRootElement(Page* page) { if (!page) return nullptr; LocalFrame* frame = toLocalFrame(page->mainFrame()); return frame->document()->accessSVGExtensions().rootElement(); }
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; m_deferredFrames.append(page->mainFrame()); // 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->mainFrame()->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 (LocalFrame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) 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); } }
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 }
USB::USB(LocalFrame& frame) : ContextLifecycleObserver(frame.document()), m_clientBinding(this) { ThreadState::current()->registerPreFinalizer(this); frame.interfaceProvider()->getInterface(mojo::GetProxy(&m_deviceManager)); m_deviceManager.set_connection_error_handler(convertToBaseCallback(WTF::bind( &USB::onDeviceManagerConnectionError, wrapWeakPersistent(this)))); m_deviceManager->SetClient(m_clientBinding.CreateInterfacePtrAndBind()); }
DOMWindow* createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures& windowFeatures, LocalDOMWindow& callingWindow, LocalFrame& firstFrame, LocalFrame& openerFrame) { LocalFrame* activeFrame = callingWindow.frame(); ASSERT(activeFrame); KURL completedURL = urlString.isEmpty() ? KURL(ParsedURLString, emptyString()) : firstFrame.document()->completeURL(urlString); if (!completedURL.isEmpty() && !completedURL.isValid()) { // Don't expose client code to invalid URLs. callingWindow.printErrorMessage("Unable to open a window with invalid URL '" + completedURL.string() + "'.\n"); return nullptr; } FrameLoadRequest frameRequest(callingWindow.document(), completedURL, frameName); frameRequest.resourceRequest().setFrameType(WebURLRequest::FrameTypeAuxiliary); frameRequest.resourceRequest().setRequestorOrigin(SecurityOrigin::create(activeFrame->document()->url())); // Normally, FrameLoader would take care of setting the referrer for a navigation that is // triggered from javascript. However, creating a window goes through sufficient processing // that it eventually enters FrameLoader as an embedder-initiated navigation. FrameLoader // assumes no responsibility for generating an embedder-initiated navigation's referrer, // so we need to ensure the proper referrer is set now. frameRequest.resourceRequest().setHTTPReferrer(SecurityPolicy::generateReferrer(activeFrame->document()->referrerPolicy(), completedURL, activeFrame->document()->outgoingReferrer())); // Records HasUserGesture before the value is invalidated inside createWindow(LocalFrame& openerFrame, ...). // This value will be set in ResourceRequest loaded in a new LocalFrame. bool hasUserGesture = UserGestureIndicator::processingUserGesture(); // We pass the opener frame for the lookupFrame in case the active frame is different from // the opener frame, and the name references a frame relative to the opener frame. bool created; ShouldSetOpener opener = windowFeatures.noopener ? NeverSetOpener : MaybeSetOpener; Frame* newFrame = createWindow(*activeFrame, openerFrame, frameRequest, windowFeatures, NavigationPolicyIgnore, opener, created); if (!newFrame) return nullptr; if (!windowFeatures.noopener) newFrame->client()->setOpener(&openerFrame); if (!newFrame->domWindow()->isInsecureScriptAccess(callingWindow, completedURL)) { if (!urlString.isEmpty() || created) newFrame->navigate(*callingWindow.document(), completedURL, false, hasUserGesture ? UserGestureStatus::Active : UserGestureStatus::None); } return newFrame->domWindow(); }
PassRefPtrWillBeRawPtr<DOMStringList> Location::ancestorOrigins() const { RefPtrWillBeRawPtr<DOMStringList> origins = DOMStringList::create(); if (!m_frame) return origins.release(); for (LocalFrame* frame = m_frame->tree().parent(); frame; frame = frame->tree().parent()) origins->append(frame->document()->securityOrigin()->toString()); return origins.release(); }