void DOMPatchSupport::patchDocument(const String& markup) { RefPtrWillBeRawPtr<Document> newDocument = nullptr; if (m_document.isHTMLDocument()) newDocument = HTMLDocument::create(); else if (m_document.isXHTMLDocument()) newDocument = XMLDocument::createXHTML(); else if (m_document.isXMLDocument()) newDocument = XMLDocument::create(); ASSERT(newDocument); newDocument->setContextFeatures(m_document.contextFeatures()); RefPtrWillBeRawPtr<DocumentParser> parser = nullptr; if (m_document.isHTMLDocument()) parser = HTMLDocumentParser::create(toHTMLDocument(*newDocument), false); else parser = XMLDocumentParser::create(*newDocument, 0); parser->insert(markup); // Use insert() so that the parser will not yield. parser->finish(); parser->detach(); OwnPtr<Digest> oldInfo = createDigest(m_document.documentElement(), 0); OwnPtr<Digest> newInfo = createDigest(newDocument->documentElement(), &m_unusedNodesMap); if (!innerPatchNode(oldInfo.get(), newInfo.get(), IGNORE_EXCEPTION)) { // Fall back to rewrite. m_document.write(markup); m_document.close(); } }
void GranularityStrategyTest::SetUp() { m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600)); m_document = toHTMLDocument(&m_dummyPageHolder->document()); ASSERT(m_document); dummyPageHolder().frame().settings()->setDefaultFontSize(12); dummyPageHolder().frame().settings()->setSelectionStrategy(SelectionStrategy::Direction); }
virtual void SetUp() { dummyPageHolder = DummyPageHolder::create(IntSize(500, 500)); dummyPageHolder->page().setDeviceScaleFactor(1.0); documentLoader = DocumentLoader::create(&dummyPageHolder->frame(), ResourceRequest("http://www.example.com"), SubstituteData()); document = toHTMLDocument(&dummyPageHolder->document()); fetchContext = &documentLoader->fetcher()->context(); FrameFetchContext::provideDocumentToContext(*fetchContext, document.get()); }
void HttpEquiv::processHttpEquivSetCookie(Document& document, const AtomicString& content) { // FIXME: make setCookie work on XML documents too; e.g. in case of <html:meta .....> if (!document.isHTMLDocument()) return; // Exception (for sandboxed documents) ignored. toHTMLDocument(document).setCookie(content, IGNORE_EXCEPTION); }
void HTMLSelectElementTest::SetUp() { Page::PageClients pageClients; fillWithEmptyClients(pageClients); m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600), &pageClients); m_document = toHTMLDocument(&m_dummyPageHolder->document()); m_document->setMimeType("text/html"); }
static EncodedJSValue namedItemGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName) { JSDOMWindowBase* thisObj = jsCast<JSDOMWindow*>(slotBase); Document* document = thisObj->impl().frame()->document(); ASSERT(BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObj->impl())); ASSERT(document); ASSERT(document->isHTMLDocument()); AtomicStringImpl* atomicPropertyName = findAtomicString(propertyName); if (!atomicPropertyName || !toHTMLDocument(document)->hasWindowNamedItem(*atomicPropertyName)) return JSValue::encode(jsUndefined()); if (UNLIKELY(toHTMLDocument(document)->windowNamedItemContainsMultipleElements(*atomicPropertyName))) { RefPtr<HTMLCollection> collection = document->windowNamedItems(atomicPropertyName); ASSERT(collection->length() > 1); return JSValue::encode(toJS(exec, thisObj->globalObject(), WTF::getPtr(collection))); } return JSValue::encode(toJS(exec, thisObj->globalObject(), toHTMLDocument(document)->windowNamedItem(*atomicPropertyName))); }
void HTMLTextFormControlElementTest::SetUp() { Page::PageClients pageClients; fillWithEmptyClients(pageClients); m_spellCheckerClient = wrapUnique(new DummySpellCheckerClient); pageClients.spellCheckerClient = m_spellCheckerClient.get(); m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600), &pageClients); m_document = toHTMLDocument(&m_dummyPageHolder->document()); m_document->documentElement()->setInnerHTML("<body><textarea id=textarea></textarea><input id=input /></body>", ASSERT_NO_EXCEPTION); m_document->view()->updateAllLifecyclePhases(); m_textControl = toHTMLTextFormControlElement(m_document->getElementById("textarea")); m_textControl->focus(); m_input = toHTMLInputElement(m_document->getElementById("input")); }
void CanvasFontCacheTest::SetUp() { Page::PageClients pageClients; fillWithEmptyClients(pageClients); m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600), &pageClients); m_document = toHTMLDocument(&m_dummyPageHolder->document()); m_document->documentElement()->setInnerHTML("<body><canvas id='c'></canvas></body>", ASSERT_NO_EXCEPTION); m_document->view()->updateAllLifecyclePhases(); m_canvasElement = toHTMLCanvasElement(m_document->getElementById("c")); String canvasType("2d"); CanvasContextCreationAttributes attributes; attributes.setAlpha(true); m_canvasElement->getCanvasRenderingContext(canvasType, attributes); context2d(); // Calling this for the checks }
v8::Handle<v8::Object> wrap(Document* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) { ASSERT(impl); if (impl->isHTMLDocument()) return wrap(toHTMLDocument(impl), creationContext, isolate); if (impl->isSVGDocument()) return wrap(toSVGDocument(impl), creationContext, isolate); v8::Handle<v8::Object> wrapper = V8Document::createWrapper(impl, creationContext, isolate); if (wrapper.IsEmpty()) return wrapper; if (!isolatedWorldForEnteredContext()) { if (Frame* frame = impl->frame()) frame->script()->windowShell(mainThreadNormalWorld())->updateDocumentWrapper(wrapper); } return wrapper; }
void SetUp() override { url = KURL(KURL(), "https://example.test/foo"); securityInfo = "security info"; mainResourceUrl = KURL(KURL(), "https://www.example.test"); MockFrameLoaderClient* client = new MockFrameLoaderClient; EXPECT_CALL(*client, didDisplayContentWithCertificateErrors(url, securityInfo)); dummyPageHolder = DummyPageHolder::create(IntSize(500, 500), nullptr, client); dummyPageHolder->page().setDeviceScaleFactor(1.0); documentLoader = DocumentLoader::create(&dummyPageHolder->frame(), ResourceRequest(mainResourceUrl), SubstituteData()); document = toHTMLDocument(&dummyPageHolder->document()); document->setURL(mainResourceUrl); fetchContext = static_cast<FrameFetchContext*>(&documentLoader->fetcher()->context()); owner = DummyFrameOwner::create(); FrameFetchContext::provideDocumentToContext(*fetchContext, document.get()); }
void V8Window::namedPropertyGetterCustom(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { LocalDOMWindow* 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); Frame* 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())) { RefPtrWillBeRawPtr<HTMLCollection> items = doc->windowNamedItems(propName); if (!items->isEmpty()) { if (items->hasExactlyOneItem()) { v8SetReturnValueFast(info, items->item(0), window); return; } v8SetReturnValueFast(info, items.release(), window); return; } } } }
void InputMethodControllerTest::SetUp() { m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600)); m_document = toHTMLDocument(&m_dummyPageHolder->document()); DCHECK(m_document); }
void HTMLIFrameElement::removedFrom(ContainerNode* insertionPoint) { HTMLFrameElementBase::removedFrom(insertionPoint); if (insertionPoint->inDocument() && document().isHTMLDocument() && !insertionPoint->isInShadowTree()) toHTMLDocument(document()).removeExtraNamedItem(m_name); }
bool JSDOMWindow::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot) { JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(cell); // When accessing a Window cross-domain, functions are always the native built-in ones, and they // are not affected by properties changed on the Window or anything in its prototype chain. // This is consistent with the behavior of Firefox. const HashEntry* entry; // We don't want any properties other than "close" and "closed" on a frameless window (i.e. one whose page got closed, // or whose iframe got removed). // FIXME: This doesn't fully match Firefox, which allows at least toString in addition to those. if (!thisObject->impl()->frame()) { // The following code is safe for cross-domain and same domain use. // It ignores any custom properties that might be set on the DOMWindow (including a custom prototype). entry = s_info.propHashTable(exec)->entry(exec, propertyName); if (entry && !(entry->attributes() & JSC::Function) && entry->propertyGetter() == jsDOMWindowClosed) { slot.setCustom(thisObject, entry->propertyGetter()); return true; } entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); if (entry && (entry->attributes() & JSC::Function) && entry->function() == jsDOMWindowPrototypeFunctionClose) { slot.setCustom(thisObject, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>); return true; } // FIXME: We should have a message here that explains why the property access/function call was // not allowed. slot.setUndefined(); return true; } // We need to check for cross-domain access here without printing the generic warning message // because we always allow access to some function, just different ones depending whether access // is allowed. String errorMessage; bool allowsAccess = shouldAllowAccessToDOMWindow(exec, thisObject->impl(), errorMessage); // Look for overrides before looking at any of our own properties, but ignore overrides completely // if this is cross-domain access. if (allowsAccess && JSGlobalObject::getOwnPropertySlot(thisObject, exec, propertyName, slot)) return true; // We need this code here because otherwise JSDOMWindowBase will stop the search before we even get to the // prototype due to the blanket same origin (shouldAllowAccessToDOMWindow) check at the end of getOwnPropertySlot. // Also, it's important to get the implementation straight out of the DOMWindow prototype regardless of // what prototype is actually set on this object. entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); if (entry) { if (entry->attributes() & JSC::Function) { if (entry->function() == jsDOMWindowPrototypeFunctionBlur) { if (!allowsAccess) { slot.setCustom(thisObject, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionBlur, 0>); return true; } } else if (entry->function() == jsDOMWindowPrototypeFunctionClose) { if (!allowsAccess) { slot.setCustom(thisObject, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>); return true; } } else if (entry->function() == jsDOMWindowPrototypeFunctionFocus) { if (!allowsAccess) { slot.setCustom(thisObject, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionFocus, 0>); return true; } } else if (entry->function() == jsDOMWindowPrototypeFunctionPostMessage) { if (!allowsAccess) { slot.setCustom(thisObject, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionPostMessage, 2>); return true; } } else if (entry->function() == jsDOMWindowPrototypeFunctionShowModalDialog) { if (!DOMWindow::canShowModalDialog(thisObject->impl()->frame())) { slot.setUndefined(); return true; } } } } else { // Allow access to toString() cross-domain, but always Object.prototype.toString. if (propertyName == exec->propertyNames().toString) { if (!allowsAccess) { slot.setCustom(thisObject, objectToStringFunctionGetter); return true; } } } entry = JSDOMWindow::s_info.propHashTable(exec)->entry(exec, propertyName); if (entry) { slot.setCustom(thisObject, entry->propertyGetter()); return true; } // Check for child frames by name before built-in properties to // match Mozilla. This does not match IE, but some sites end up // naming frames things that conflict with window properties that // are in Moz but not IE. Since we have some of these, we have to do // it the Moz way. if (thisObject->impl()->frame()->tree()->scopedChild(propertyNameToAtomicString(propertyName))) { slot.setCustom(thisObject, childFrameGetter); return true; } // Do prototype lookup early so that functions and attributes in the prototype can have // precedence over the index and name getters. JSValue proto = thisObject->prototype(); if (proto.isObject()) { if (asObject(proto)->getPropertySlot(exec, propertyName, slot)) { if (!allowsAccess) { thisObject->printErrorMessage(errorMessage); slot.setUndefined(); } return true; } } // FIXME: Search the whole frame hierarchy somewhere around here. // We need to test the correct priority order. // allow window[1] or parent[1] etc. (#56983) unsigned i = propertyName.asIndex(); if (i < thisObject->impl()->frame()->tree()->scopedChildCount()) { ASSERT(i != PropertyName::NotAnIndex); slot.setCustomIndex(thisObject, i, indexGetter); return true; } if (!allowsAccess) { thisObject->printErrorMessage(errorMessage); slot.setUndefined(); return true; } // Allow shortcuts like 'Image1' instead of document.images.Image1 Document* document = thisObject->impl()->frame()->document(); if (document->isHTMLDocument()) { AtomicStringImpl* atomicPropertyName = findAtomicString(propertyName); if (atomicPropertyName && (toHTMLDocument(document)->hasNamedItem(atomicPropertyName) || document->hasElementWithId(atomicPropertyName))) { slot.setCustom(thisObject, namedItemGetter); return true; } } return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); }
void SetUp() override { m_dummyPageHolder = DummyPageHolder::create(); m_document = toHTMLDocument(&m_dummyPageHolder->document()); }
bool JSDOMWindow::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor) { JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(object); // Never allow cross-domain getOwnPropertyDescriptor if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->impl())) return false; const HashEntry* entry; // We don't want any properties other than "close" and "closed" on a closed window. if (!thisObject->impl()->frame()) { // The following code is safe for cross-domain and same domain use. // It ignores any custom properties that might be set on the DOMWindow (including a custom prototype). entry = s_info.propHashTable(exec)->entry(exec, propertyName); if (entry && !(entry->attributes() & JSC::Function) && entry->propertyGetter() == jsDOMWindowClosed) { descriptor.setDescriptor(jsBoolean(true), ReadOnly | DontDelete | DontEnum); return true; } entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); if (entry && (entry->attributes() & JSC::Function) && entry->function() == jsDOMWindowPrototypeFunctionClose) { PropertySlot slot; slot.setCustom(thisObject, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>); descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); return true; } descriptor.setUndefined(); return true; } entry = JSDOMWindow::s_info.propHashTable(exec)->entry(exec, propertyName); if (entry) { PropertySlot slot; slot.setCustom(thisObject, entry->propertyGetter()); descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes()); return true; } // Check for child frames by name before built-in properties to // match Mozilla. This does not match IE, but some sites end up // naming frames things that conflict with window properties that // are in Moz but not IE. Since we have some of these, we have to do // it the Moz way. if (thisObject->impl()->frame()->tree()->scopedChild(propertyNameToAtomicString(propertyName))) { PropertySlot slot; slot.setCustom(thisObject, childFrameGetter); descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); return true; } unsigned i = propertyName.asIndex(); if (i < thisObject->impl()->frame()->tree()->scopedChildCount()) { ASSERT(i != PropertyName::NotAnIndex); PropertySlot slot; slot.setCustomIndex(thisObject, i, indexGetter); descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); return true; } // Allow shortcuts like 'Image1' instead of document.images.Image1 Document* document = thisObject->impl()->frame()->document(); if (document->isHTMLDocument()) { AtomicStringImpl* atomicPropertyName = findAtomicString(propertyName); if (atomicPropertyName && (toHTMLDocument(document)->hasNamedItem(atomicPropertyName) || document->hasElementWithId(atomicPropertyName))) { PropertySlot slot; slot.setCustom(thisObject, namedItemGetter); descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); return true; } } return Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); }
bool JSDOMWindow::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned index, PropertySlot& slot) { JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(cell); if (!thisObject->impl()->frame()) { // FIXME: We should have a message here that explains why the property access/function call was // not allowed. slot.setUndefined(); return true; } // We need to check for cross-domain access here without printing the generic warning message // because we always allow access to some function, just different ones depending whether access // is allowed. String errorMessage; bool allowsAccess = shouldAllowAccessToDOMWindow(exec, thisObject->impl(), errorMessage); // Look for overrides before looking at any of our own properties, but ignore overrides completely // if this is cross-domain access. if (allowsAccess && JSGlobalObject::getOwnPropertySlotByIndex(thisObject, exec, index, slot)) return true; PropertyName propertyName = Identifier::from(exec, index); // Check for child frames by name before built-in properties to // match Mozilla. This does not match IE, but some sites end up // naming frames things that conflict with window properties that // are in Moz but not IE. Since we have some of these, we have to do // it the Moz way. if (thisObject->impl()->frame()->tree()->scopedChild(propertyNameToAtomicString(propertyName))) { slot.setCustom(thisObject, childFrameGetter); return true; } // Do prototype lookup early so that functions and attributes in the prototype can have // precedence over the index and name getters. JSValue proto = thisObject->prototype(); if (proto.isObject()) { if (asObject(proto)->getPropertySlot(exec, index, slot)) { if (!allowsAccess) { thisObject->printErrorMessage(errorMessage); slot.setUndefined(); } return true; } } // FIXME: Search the whole frame hierarchy somewhere around here. // We need to test the correct priority order. // allow window[1] or parent[1] etc. (#56983) if (index < thisObject->impl()->frame()->tree()->scopedChildCount()) { ASSERT(index != PropertyName::NotAnIndex); slot.setCustomIndex(thisObject, index, indexGetter); return true; } if (!allowsAccess) { thisObject->printErrorMessage(errorMessage); slot.setUndefined(); return true; } // Allow shortcuts like 'Image1' instead of document.images.Image1 Document* document = thisObject->impl()->frame()->document(); if (document->isHTMLDocument()) { AtomicStringImpl* atomicPropertyName = findAtomicString(propertyName); if (atomicPropertyName && (toHTMLDocument(document)->hasNamedItem(atomicPropertyName) || document->hasElementWithId(atomicPropertyName))) { slot.setCustom(thisObject, namedItemGetter); return true; } } return Base::getOwnPropertySlotByIndex(thisObject, exec, index, slot); }
void FrameSelectionTest::SetUp() { m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600)); m_document = toHTMLDocument(&m_dummyPageHolder->document()); ASSERT(m_document); }
void ComposedTreeTraversalTest::SetUp() { m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600)); m_document = toHTMLDocument(&m_dummyPageHolder->document()); ASSERT(m_document); }
void V8Window::namedPropertyGetterCustom( const AtomicString& name, const v8::PropertyCallbackInfo<v8::Value>& info) { DOMWindow* window = V8Window::toImpl(info.Holder()); if (!window) return; Frame* frame = window->frame(); // window is detached from a frame. if (!frame) return; // Note that the spec doesn't allow any cross-origin named access to the // window object. However, UAs have traditionally allowed named access to // named child browsing contexts, even across origins. So first, search child // frames for a frame with a matching name. Frame* child = frame->tree().scopedChild(name); if (child) { v8SetReturnValueFast(info, child->domWindow(), window); return; } // If the frame is remote, the caller will never be able to access further // named results. if (!frame->isLocalFrame()) return; // Search named items in the document. Document* doc = toLocalFrame(frame)->document(); if (!doc || !doc->isHTMLDocument()) return; // This is an AllCanRead interceptor. Check that the caller has access to the // named results. if (!BindingSecurity::shouldAllowAccessTo( currentDOMWindow(info.GetIsolate()), window, BindingSecurity::ErrorReportOption::DoNotReport)) return; bool hasNamedItem = toHTMLDocument(doc)->hasNamedItem(name); bool hasIdItem = doc->hasElementWithId(name); if (!hasNamedItem && !hasIdItem) return; if (!hasNamedItem && hasIdItem && !doc->containsMultipleElementsWithId(name)) { v8SetReturnValueFast(info, doc->getElementById(name), window); return; } HTMLCollection* items = doc->windowNamedItems(name); if (!items->isEmpty()) { // TODO(esprehn): Firefox doesn't return an HTMLCollection here if there's // multiple with the same name, but Chrome and Safari does. What's the // right behavior? if (items->hasExactlyOneItem()) { v8SetReturnValueFast(info, items->item(0), window); return; } v8SetReturnValueFast(info, items, window); return; } }
void LayoutThemeTest::SetUp() { m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600)); m_document = toHTMLDocument(&m_dummyPageHolder->document()); ASSERT(m_document); }
bool JSDOMWindow::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) { JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(object); // When accessing a Window cross-domain, functions are always the native built-in ones, and they // are not affected by properties changed on the Window or anything in its prototype chain. // This is consistent with the behavior of Firefox. // We don't want any properties other than "close" and "closed" on a frameless window (i.e. one whose page got closed, // or whose iframe got removed). // FIXME: This doesn't fully match Firefox, which allows at least toString in addition to those. if (!thisObject->impl().frame()) { // The following code is safe for cross-domain and same domain use. // It ignores any custom properties that might be set on the DOMWindow (including a custom prototype). if (propertyName == exec->propertyNames().closed) { slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, jsDOMWindowClosed); return true; } if (propertyName == exec->propertyNames().close) { slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>); return true; } // FIXME: We should have a message here that explains why the property access/function call was // not allowed. slot.setUndefined(); return true; } else slot.setWatchpointSet(thisObject->m_windowCloseWatchpoints); // We need to check for cross-domain access here without printing the generic warning message // because we always allow access to some function, just different ones depending whether access // is allowed. String errorMessage; bool allowsAccess = shouldAllowAccessToDOMWindow(exec, thisObject->impl(), errorMessage); // Look for overrides before looking at any of our own properties, but ignore overrides completely // if this is cross-domain access. if (allowsAccess && JSGlobalObject::getOwnPropertySlot(thisObject, exec, propertyName, slot)) return true; // We need this code here because otherwise JSDOMWindowBase will stop the search before we even get to the // prototype due to the blanket same origin (shouldAllowAccessToDOMWindow) check at the end of getOwnPropertySlot. // Also, it's important to get the implementation straight out of the DOMWindow prototype regardless of // what prototype is actually set on this object. if (propertyName == exec->propertyNames().blur) { if (!allowsAccess) { slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionBlur, 0>); return true; } } else if (propertyName == exec->propertyNames().close) { if (!allowsAccess) { slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>); return true; } } else if (propertyName == exec->propertyNames().focus) { if (!allowsAccess) { slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionFocus, 0>); return true; } } else if (propertyName == exec->propertyNames().postMessage) { if (!allowsAccess) { slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionPostMessage, 2>); return true; } } else if (propertyName == exec->propertyNames().showModalDialog) { if (!DOMWindow::canShowModalDialog(thisObject->impl().frame())) { slot.setUndefined(); return true; } } else if (propertyName == exec->propertyNames().toString) { // Allow access to toString() cross-domain, but always Object.prototype.toString. if (!allowsAccess) { slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, objectToStringFunctionGetter); return true; } } const HashTableValue* entry = JSDOMWindow::info()->propHashTable(exec)->entry(exec, propertyName); if (entry) { slot.setCacheableCustom(thisObject, allowsAccess ? entry->attributes() : ReadOnly | DontDelete | DontEnum, entry->propertyGetter()); return true; } #if ENABLE(USER_MESSAGE_HANDLERS) if (propertyName == exec->propertyNames().webkit && thisObject->impl().shouldHaveWebKitNamespaceForWorld(thisObject->world())) { slot.setCacheableCustom(thisObject, allowsAccess ? DontDelete | ReadOnly : ReadOnly | DontDelete | DontEnum, jsDOMWindowWebKit); return true; } #endif // Do prototype lookup early so that functions and attributes in the prototype can have // precedence over the index and name getters. JSValue proto = thisObject->prototype(); if (proto.isObject()) { if (asObject(proto)->getPropertySlot(exec, propertyName, slot)) { if (!allowsAccess) { thisObject->printErrorMessage(errorMessage); slot.setUndefined(); } return true; } } // After this point it is no longer valid to cache any results because of // the impure nature of the property accesses which follow. We can move this // statement further down when we add ways to mitigate these impurities with, // for example, watchpoints. slot.disableCaching(); // Check for child frames by name before built-in properties to // match Mozilla. This does not match IE, but some sites end up // naming frames things that conflict with window properties that // are in Moz but not IE. Since we have some of these, we have to do // it the Moz way. if (thisObject->impl().frame()->tree().scopedChild(propertyNameToAtomicString(propertyName))) { slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, childFrameGetter); return true; } // FIXME: Search the whole frame hierarchy somewhere around here. // We need to test the correct priority order. // allow window[1] or parent[1] etc. (#56983) unsigned i = propertyName.asIndex(); if (i < thisObject->impl().frame()->tree().scopedChildCount()) { ASSERT(i != PropertyName::NotAnIndex); slot.setValue(thisObject, ReadOnly | DontDelete | DontEnum, toJS(exec, thisObject->impl().frame()->tree().scopedChild(i)->document()->domWindow())); return true; } if (!allowsAccess) { thisObject->printErrorMessage(errorMessage); slot.setUndefined(); return true; } // Allow shortcuts like 'Image1' instead of document.images.Image1 Document* document = thisObject->impl().frame()->document(); if (document->isHTMLDocument()) { AtomicStringImpl* atomicPropertyName = findAtomicString(propertyName); if (atomicPropertyName && toHTMLDocument(document)->hasWindowNamedItem(*atomicPropertyName)) { slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, namedItemGetter); return true; } } return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); }