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); }
void StorageArea::dispatchSessionStorageEvent(const String& key, const String& oldValue, const String& newValue, SecurityOrigin* securityOrigin, const KURL& pageURL, const blink::WebStorageNamespace& sessionNamespace, blink::WebStorageArea* sourceAreaInstance, bool originatedInProcess) { Page* page = findPageWithSessionStorageNamespace(sessionNamespace); if (!page) return; for (LocalFrame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) { Storage* storage = frame->domWindow()->optionalSessionStorage(); if (storage && frame->document()->securityOrigin()->canAccess(securityOrigin) && !isEventSource(storage, sourceAreaInstance)) frame->domWindow()->enqueueWindowEvent(StorageEvent::create(EventTypeNames::storage, key, oldValue, newValue, pageURL, storage)); } InspectorInstrumentation::didDispatchDOMStorageEvent(page, key, oldValue, newValue, SessionStorage, securityOrigin); }
void StorageArea::dispatchLocalStorageEvent(const String& key, const String& oldValue, const String& newValue, SecurityOrigin* securityOrigin, const KURL& pageURL, blink::WebStorageArea* sourceAreaInstance, bool originatedInProcess) { // FIXME: This looks suspicious. Why doesn't this use allPages instead? const HashSet<Page*>& pages = Page::ordinaryPages(); for (HashSet<Page*>::const_iterator it = pages.begin(); it != pages.end(); ++it) { for (LocalFrame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) { Storage* storage = frame->domWindow()->optionalLocalStorage(); if (storage && frame->document()->securityOrigin()->canAccess(securityOrigin) && !isEventSource(storage, sourceAreaInstance)) frame->domWindow()->enqueueWindowEvent(StorageEvent::create(EventTypeNames::storage, key, oldValue, newValue, pageURL, storage)); } InspectorInstrumentation::didDispatchDOMStorageEvent(*it, key, oldValue, newValue, LocalStorage, securityOrigin); } }
LocalFrame* createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures& windowFeatures, DOMWindow& callingWindow, LocalFrame& firstFrame, LocalFrame& openerFrame, DOMWindow::PrepareDialogFunction function, void* functionContext) { 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 0; } // For whatever reason, Firefox uses the first frame to determine the outgoingReferrer. We replicate that behavior here. Referrer referrer(SecurityPolicy::generateReferrerHeader(firstFrame.document()->referrerPolicy(), completedURL, firstFrame.document()->outgoingReferrer()), firstFrame.document()->referrerPolicy()); ResourceRequest request(completedURL, referrer); FrameLoader::addHTTPOriginIfNeeded(request, AtomicString(firstFrame.document()->outgoingOrigin())); FrameLoadRequest frameRequest(callingWindow.document(), request, frameName); // 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; LocalFrame* newFrame = createWindow(*activeFrame, openerFrame, frameRequest, windowFeatures, NavigationPolicyIgnore, MaybeSendReferrer, created); if (!newFrame) return 0; if (newFrame != &openerFrame && newFrame != openerFrame.tree().top()) newFrame->loader().forceSandboxFlags(openerFrame.document()->sandboxFlags()); newFrame->loader().setOpener(&openerFrame); newFrame->page()->setOpenedByDOM(); if (newFrame->domWindow()->isInsecureScriptAccess(callingWindow, completedURL)) return newFrame; if (function) function(newFrame->domWindow(), functionContext); if (created) { FrameLoadRequest request(callingWindow.document(), ResourceRequest(completedURL, referrer)); newFrame->loader().load(request); } else if (!urlString.isEmpty()) { newFrame->navigationScheduler().scheduleLocationChange(callingWindow.document(), completedURL.string(), referrer, false); } return newFrame; }
void Location::setLocation(const String& url, DOMWindow* callingWindow, DOMWindow* enteredWindow) { ASSERT(m_frame); LocalFrame* frame = m_frame->loader().findFrameForNavigation(nullAtom, callingWindow->document()); if (!frame) return; frame->domWindow()->setLocation(url, callingWindow, enteredWindow); }
LocalFrame* createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures& windowFeatures, LocalDOMWindow& callingWindow, LocalFrame& firstFrame, LocalFrame& openerFrame, LocalDOMWindow::PrepareDialogFunction function, void* functionContext) { 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); // 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())); // 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; LocalFrame* newFrame = createWindow(*activeFrame, openerFrame, frameRequest, windowFeatures, NavigationPolicyIgnore, MaybeSendReferrer, created); if (!newFrame) return nullptr; if (newFrame != &openerFrame && newFrame != openerFrame.tree().top()) newFrame->loader().forceSandboxFlags(openerFrame.document()->sandboxFlags()); newFrame->loader().setOpener(&openerFrame); if (newFrame->domWindow()->isInsecureScriptAccess(callingWindow, completedURL)) return newFrame; if (function) function(newFrame->domWindow(), functionContext); if (created) newFrame->loader().load(FrameLoadRequest(callingWindow.document(), completedURL)); else if (!urlString.isEmpty()) newFrame->navigationScheduler().scheduleLocationChange(callingWindow.document(), completedURL.string(), false); return newFrame; }
static void dispatchCompositionEndEvent(LocalFrame& frame, const String& text) { // We should send this event before sending a TextEvent as written in // Section 6.2.2 and 6.2.3 of the DOM Event specification. Element* target = frame.document()->focusedElement(); if (!target) return; RefPtrWillBeRawPtr<CompositionEvent> event = CompositionEvent::create(EventTypeNames::compositionend, frame.domWindow(), text); target->dispatchEvent(event); }
bool WebPagePopupImpl::initializePage() { Page::PageClients pageClients; fillWithEmptyClients(pageClients); m_chromeClient = PagePopupChromeClient::create(this); pageClients.chromeClient = m_chromeClient.get(); Settings& mainSettings = m_webView->page()->settings(); m_page = Page::create(pageClients); m_page->settings().setScriptEnabled(true); m_page->settings().setAllowScriptsToCloseWindows(true); m_page->settings().setDeviceSupportsTouch(mainSettings.deviceSupportsTouch()); m_page->settings().setMinimumFontSize(mainSettings.minimumFontSize()); m_page->settings().setMinimumLogicalFontSize( mainSettings.minimumLogicalFontSize()); // FIXME: Should we support enabling a11y while a popup is shown? m_page->settings().setAccessibilityEnabled( mainSettings.accessibilityEnabled()); m_page->settings().setScrollAnimatorEnabled( mainSettings.scrollAnimatorEnabled()); provideContextFeaturesTo(*m_page, WTF::makeUnique<PagePopupFeaturesClient>()); DEFINE_STATIC_LOCAL(FrameLoaderClient, emptyFrameLoaderClient, (EmptyFrameLoaderClient::create())); LocalFrame* frame = LocalFrame::create(&emptyFrameLoaderClient, &m_page->frameHost(), 0); frame->setPagePopupOwner(m_popupClient->ownerElement()); frame->setView(FrameView::create(*frame)); frame->init(); frame->view()->setParentVisible(true); frame->view()->setSelfVisible(true); frame->view()->setTransparent(false); if (AXObjectCache* cache = m_popupClient->ownerElement().document().existingAXObjectCache()) cache->childrenChanged(&m_popupClient->ownerElement()); DCHECK(frame->domWindow()); PagePopupSupplement::install(*frame, *this, m_popupClient); DCHECK_EQ(m_popupClient->ownerElement().document().existingAXObjectCache(), frame->document()->existingAXObjectCache()); RefPtr<SharedBuffer> data = SharedBuffer::create(); m_popupClient->writeDocument(data.get()); frame->loader().load(FrameLoadRequest( 0, blankURL(), SubstituteData(data, "text/html", "UTF-8", KURL(), ForceSynchronousLoad))); frame->setPageZoomFactor(m_popupClient->zoomFactor()); return true; }
// Checks that the domain is set to the actual MHTML file, not the URL it was // generated from. TEST_F(MHTMLTest, CheckDomain) { const char kFileURL[] = "file:///simple_test.mht"; // Register the mocked frame and load it. WebURL url = toKURL(kFileURL); registerMockedURLLoad(kFileURL, WebString::fromUTF8("simple_test.mht")); loadURLInTopFrame(url); ASSERT_TRUE(page()); LocalFrame* frame = toLocalFrame(page()->mainFrame()); ASSERT_TRUE(frame); Document* document = frame->document(); ASSERT_TRUE(document); EXPECT_STREQ(kFileURL, frame->domWindow()->location()->href().ascii().data()); SecurityOrigin* origin = document->securityOrigin(); EXPECT_STRNE("localhost", origin->domain().ascii().data()); }
void V8Window::namedPropertyGetterCustom(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { DOMWindow* window = V8Window::toNative(info.Holder()); if (!window) return; LocalFrame* frame = window->frame(); // window is detached from a frame. if (!frame) return; // Search sub-frames. AtomicString propName = toCoreAtomicString(name); LocalFrame* child = frame->tree().scopedChild(propName); if (child) { v8SetReturnValueFast(info, child->domWindow(), window); return; } // Search IDL functions defined in the prototype if (!info.Holder()->GetRealNamedProperty(name).IsEmpty()) return; // Search named items in the document. Document* doc = frame->document(); if (doc && doc->isHTMLDocument()) { if (toHTMLDocument(doc)->hasNamedItem(propName) || doc->hasElementWithId(propName.impl())) { RefPtr<HTMLCollection> items = doc->windowNamedItems(propName); if (!items->isEmpty()) { if (items->hasExactlyOneItem()) { v8SetReturnValueFast(info, items->item(0), window); return; } v8SetReturnValueFast(info, items.release(), window); return; } } } }