summaryrefslogtreecommitdiff
path: root/Source/WebCore/bindings/js/JSHTMLDocumentCustom.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/bindings/js/JSHTMLDocumentCustom.cpp')
-rw-r--r--Source/WebCore/bindings/js/JSHTMLDocumentCustom.cpp180
1 files changed, 100 insertions, 80 deletions
diff --git a/Source/WebCore/bindings/js/JSHTMLDocumentCustom.cpp b/Source/WebCore/bindings/js/JSHTMLDocumentCustom.cpp
index 7e7bb5a44..2003cacac 100644
--- a/Source/WebCore/bindings/js/JSHTMLDocumentCustom.cpp
+++ b/Source/WebCore/bindings/js/JSHTMLDocumentCustom.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,24 +26,11 @@
#include "config.h"
#include "JSHTMLDocument.h"
-#include "Frame.h"
-#include "HTMLAllCollection.h"
-#include "HTMLBodyElement.h"
-#include "HTMLCollection.h"
-#include "HTMLDocument.h"
-#include "HTMLElement.h"
#include "HTMLIFrameElement.h"
-#include "HTMLNames.h"
-#include "JSDOMWindow.h"
#include "JSDOMWindowCustom.h"
-#include "JSDOMWindowShell.h"
#include "JSHTMLCollection.h"
-#include "JSMainThreadExecState.h"
#include "SegmentedString.h"
-#include "DocumentParser.h"
-#include <runtime/Error.h>
-#include <runtime/JSCell.h>
-#include <wtf/unicode/CharacterNames.h>
+#include <runtime/Lookup.h>
using namespace JSC;
@@ -51,120 +38,153 @@ namespace WebCore {
using namespace HTMLNames;
-bool JSHTMLDocument::canGetItemsForName(ExecState*, HTMLDocument* document, PropertyName propertyName)
+JSValue toJSNewlyCreated(ExecState* state, JSDOMGlobalObject* globalObject, Ref<HTMLDocument>&& passedDocument)
{
- AtomicStringImpl* atomicPropertyName = findAtomicString(propertyName);
- return atomicPropertyName && document->hasDocumentNamedItem(*atomicPropertyName);
+ auto& document = passedDocument.get();
+ auto* wrapper = createWrapper<HTMLDocument>(globalObject, WTFMove(passedDocument));
+ reportMemoryForDocumentIfFrameless(*state, document);
+ return wrapper;
}
-EncodedJSValue JSHTMLDocument::nameGetter(ExecState* exec, EncodedJSValue slotBase, EncodedJSValue, PropertyName propertyName)
+JSValue toJS(ExecState* state, JSDOMGlobalObject* globalObject, HTMLDocument& document)
{
- JSHTMLDocument* thisObj = jsCast<JSHTMLDocument*>(JSValue::decode(slotBase));
- HTMLDocument& document = thisObj->impl();
+ if (auto* wrapper = cachedDocumentWrapper(*state, *globalObject, document))
+ return wrapper;
+ return toJSNewlyCreated(state, globalObject, Ref<HTMLDocument>(document));
+}
+
+bool JSHTMLDocument::getOwnPropertySlot(JSObject* object, ExecState* state, PropertyName propertyName, PropertySlot& slot)
+{
+ auto& thisObject = *jsCast<JSHTMLDocument*>(object);
+ ASSERT_GC_OBJECT_INHERITS(object, info());
+
+ if (propertyName == "open") {
+ if (Base::getOwnPropertySlot(&thisObject, state, propertyName, slot))
+ return true;
+ slot.setCustom(&thisObject, ReadOnly | DontDelete | DontEnum, nonCachingStaticFunctionGetter<jsHTMLDocumentPrototypeFunctionOpen, 2>);
+ return true;
+ }
+
+ JSValue value;
+ if (thisObject.nameGetter(state, propertyName, value)) {
+ slot.setValue(&thisObject, ReadOnly | DontDelete | DontEnum, value);
+ return true;
+ }
- AtomicStringImpl* atomicPropertyName = findAtomicString(propertyName);
+ return Base::getOwnPropertySlot(&thisObject, state, propertyName, slot);
+}
+
+bool JSHTMLDocument::nameGetter(ExecState* state, PropertyName propertyName, JSValue& value)
+{
+ auto& document = wrapped();
+
+ auto* atomicPropertyName = propertyName.publicName();
if (!atomicPropertyName || !document.hasDocumentNamedItem(*atomicPropertyName))
- return JSValue::encode(jsUndefined());
+ return false;
if (UNLIKELY(document.documentNamedItemContainsMultipleElements(*atomicPropertyName))) {
- RefPtr<HTMLCollection> collection = document.documentNamedItems(atomicPropertyName);
+ auto collection = document.documentNamedItems(atomicPropertyName);
ASSERT(collection->length() > 1);
- return JSValue::encode(toJS(exec, thisObj->globalObject(), WTF::getPtr(collection)));
+ value = toJS(state, globalObject(), collection);
+ return true;
}
- Element* element = document.documentNamedItem(*atomicPropertyName);
- if (UNLIKELY(element->hasTagName(iframeTag))) {
- if (Frame* frame = toHTMLIFrameElement(element)->contentFrame())
- return JSValue::encode(toJS(exec, frame));
+ auto& element = *document.documentNamedItem(*atomicPropertyName);
+ if (UNLIKELY(is<HTMLIFrameElement>(element))) {
+ if (auto* frame = downcast<HTMLIFrameElement>(element).contentFrame()) {
+ value = toJS(state, frame);
+ return true;
+ }
}
- return JSValue::encode(toJS(exec, thisObj->globalObject(), element));
+ value = toJS(state, globalObject(), element);
+ return true;
}
// Custom attributes
-JSValue JSHTMLDocument::all(ExecState* exec) const
+JSValue JSHTMLDocument::all(ExecState& state) const
{
// If "all" has been overwritten, return the overwritten value
- JSValue v = getDirect(exec->vm(), Identifier(exec, "all"));
- if (v)
- return v;
+ if (auto overwrittenValue = getDirect(state.vm(), Identifier::fromString(&state, "all")))
+ return overwrittenValue;
- return toJS(exec, globalObject(), impl().all());
+ return toJS(&state, globalObject(), wrapped().all());
}
-void JSHTMLDocument::setAll(ExecState* exec, JSValue value)
+void JSHTMLDocument::setAll(ExecState& state, JSValue value)
{
// Add "all" to the property map.
- putDirect(exec->vm(), Identifier(exec, "all"), value);
+ putDirect(state.vm(), Identifier::fromString(&state, "all"), value);
+}
+
+static inline Document* findCallingDocument(ExecState& state)
+{
+ CallerFunctor functor;
+ state.iterate(functor);
+ auto* callerFrame = functor.callerFrame();
+ if (!callerFrame)
+ return nullptr;
+ return asJSDOMWindow(callerFrame->lexicalGlobalObject())->wrapped().document();
}
// Custom functions
-JSValue JSHTMLDocument::open(ExecState* exec)
+JSValue JSHTMLDocument::open(ExecState& state)
{
+ VM& vm = state.vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
// For compatibility with other browsers, pass open calls with more than 2 parameters to the window.
- if (exec->argumentCount() > 2) {
- if (Frame* frame = impl().frame()) {
- JSDOMWindowShell* wrapper = toJSDOMWindowShell(frame, currentWorld(exec));
- if (wrapper) {
- JSValue function = wrapper->get(exec, Identifier(exec, "open"));
+ if (state.argumentCount() > 2) {
+ if (auto* frame = wrapped().frame()) {
+ if (auto* wrapper = toJSDOMWindowShell(frame, currentWorld(&state))) {
+ auto function = wrapper->get(&state, Identifier::fromString(&state, "open"));
CallData callData;
- CallType callType = ::getCallData(function, callData);
- if (callType == CallTypeNone)
- return throwTypeError(exec);
- return JSMainThreadExecState::call(exec, function, callType, callData, wrapper, ArgList(exec));
+ auto callType = ::getCallData(function, callData);
+ if (callType == CallType::None)
+ return throwTypeError(&state, scope);
+ return JSC::call(&state, function, callType, callData, wrapper, ArgList(&state));
}
}
return jsUndefined();
}
- // document.open clobbers the security context of the document and
- // aliases it with the active security context.
- Document* activeDocument = asJSDOMWindow(exec->lexicalGlobalObject())->impl().document();
-
- // In the case of two parameters or fewer, do a normal document open.
- impl().open(activeDocument);
+ // Calling document.open clobbers the security context of the document and aliases it with the active security context.
+ // FIXME: Is it correct that this does not use findCallingDocument as the write function below does?
+ wrapped().open(asJSDOMWindow(state.lexicalGlobalObject())->wrapped().document());
+ // FIXME: Why do we return the document instead of returning undefined?
return this;
}
enum NewlineRequirement { DoNotAddNewline, DoAddNewline };
-static inline void documentWrite(ExecState* exec, HTMLDocument* document, NewlineRequirement addNewline)
+static inline JSValue documentWrite(ExecState& state, JSHTMLDocument& document, NewlineRequirement addNewline)
{
- // DOM only specifies single string argument, but browsers allow multiple or no arguments.
-
- size_t size = exec->argumentCount();
-
- String firstString = exec->argument(0).toString(exec)->value(exec);
- SegmentedString segmentedString = firstString;
- if (size != 1) {
- if (!size)
- segmentedString.clear();
- else {
- for (size_t i = 1; i < size; ++i) {
- String subsequentString = exec->uncheckedArgument(i).toString(exec)->value(exec);
- segmentedString.append(SegmentedString(subsequentString));
- }
- }
+ VM& vm = state.vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ SegmentedString segmentedString;
+ size_t argumentCount = state.argumentCount();
+ for (size_t i = 0; i < argumentCount; ++i) {
+ segmentedString.append(state.uncheckedArgument(i).toWTFString(&state));
+ RETURN_IF_EXCEPTION(scope, { });
}
if (addNewline)
- segmentedString.append(SegmentedString(String(&newlineCharacter, 1)));
+ segmentedString.append(String { "\n" });
- Document* activeDocument = asJSDOMWindow(exec->lexicalGlobalObject())->impl().document();
- document->write(segmentedString, activeDocument);
+ document.wrapped().write(WTFMove(segmentedString), findCallingDocument(state));
+ return jsUndefined();
}
-JSValue JSHTMLDocument::write(ExecState* exec)
+JSValue JSHTMLDocument::write(ExecState& state)
{
- documentWrite(exec, &impl(), DoNotAddNewline);
- return jsUndefined();
+ return documentWrite(state, *this, DoNotAddNewline);
}
-JSValue JSHTMLDocument::writeln(ExecState* exec)
+JSValue JSHTMLDocument::writeln(ExecState& state)
{
- documentWrite(exec, &impl(), DoAddNewline);
- return jsUndefined();
+ return documentWrite(state, *this, DoAddNewline);
}
} // namespace WebCore