diff options
author | Upstream <upstream-import@none> | 1970-01-12 13:46:40 +0000 |
---|---|---|
committer | Upstream <upstream-import@none> | 1970-01-12 13:46:40 +0000 |
commit | d8543bb6618c17b12da906afa77d216f58cf4058 (patch) | |
tree | c58dc05ed86825bd0ef8d305d58c8205106b540f /WebCore/bindings/js | |
download | external_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.zip external_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.tar.gz external_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.tar.bz2 |
external/webkit r30707
Diffstat (limited to 'WebCore/bindings/js')
102 files changed, 13525 insertions, 0 deletions
diff --git a/WebCore/bindings/js/GCController.cpp b/WebCore/bindings/js/GCController.cpp new file mode 100644 index 0000000..94c48a1 --- /dev/null +++ b/WebCore/bindings/js/GCController.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "GCController.h" + +#include <kjs/JSLock.h> +#include <kjs/collector.h> + +#if USE(PTHREADS) +#include <pthread.h> +#endif + +using namespace KJS; + +namespace WebCore { + +#if USE(PTHREADS) + +static void* collect(void*) +{ + JSLock lock; + Collector::collect(); + return 0; +} + +#endif + +GCController& gcController() +{ + static GCController staticGCController; + return staticGCController; +} + +GCController::GCController() + : m_GCTimer(this, &GCController::gcTimerFired) +{ +} + +void GCController::garbageCollectSoon() +{ + if (!m_GCTimer.isActive()) + m_GCTimer.startOneShot(0); +} + +void GCController::gcTimerFired(Timer<GCController>*) +{ + JSLock lock; + Collector::collect(); +} + +void GCController::garbageCollectNow() +{ + JSLock lock; + Collector::collect(); +} + +void GCController::garbageCollectOnAlternateThreadForDebugging(bool waitUntilDone) +{ +#if USE(PTHREADS) + pthread_t thread; + pthread_create(&thread, NULL, collect, NULL); + + if (waitUntilDone) { + JSLock::DropAllLocks dropLocks; // Otherwise our lock would deadlock the collect thread we're joining + pthread_join(thread, NULL); + } +#endif +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/GCController.h b/WebCore/bindings/js/GCController.h new file mode 100644 index 0000000..452019a --- /dev/null +++ b/WebCore/bindings/js/GCController.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GCController_h +#define GCController_h + +#include <wtf/Noncopyable.h> +#include "Timer.h" + +namespace WebCore { + + class GCController : Noncopyable { + friend GCController& gcController(); + + public: + void garbageCollectSoon(); + void garbageCollectNow(); // It's better to call garbageCollectSoon, unless you have a specific reason not to. + + void garbageCollectOnAlternateThreadForDebugging(bool waitUntilDone); // Used for stress testing. + + private: + GCController(); // Use gcController() instead + void gcTimerFired(Timer<GCController>*); + + Timer<GCController> m_GCTimer; + }; + + // Function to obtain the global GC controller. + GCController& gcController(); + +} // namespace WebCore + +#endif // GCController_h diff --git a/WebCore/bindings/js/JSAttrCustom.cpp b/WebCore/bindings/js/JSAttrCustom.cpp new file mode 100644 index 0000000..c7d3848 --- /dev/null +++ b/WebCore/bindings/js/JSAttrCustom.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSAttr.h" + +#include "CSSHelper.h" +#include "HTMLFrameElementBase.h" +#include "HTMLNames.h" + +using namespace KJS; + +namespace WebCore { + +using namespace HTMLNames; + +void JSAttr::setValue(ExecState* exec, JSValue* value) +{ + Attr* imp = static_cast<Attr*>(impl()); + String attrValue = valueToStringWithNullCheck(exec, value); + + Element* ownerElement = imp->ownerElement(); + if (ownerElement && (ownerElement->hasTagName(iframeTag) || ownerElement->hasTagName(frameTag))) { + if (equalIgnoringCase(imp->name(), "src") && protocolIs(parseURL(attrValue), "javascript")) { + if (!checkNodeSecurity(exec, static_cast<HTMLFrameElementBase*>(ownerElement)->contentDocument())) + return; + } + } + + ExceptionCode ec = 0; + imp->setValue(attrValue, ec); + setDOMException(exec, ec); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSAudioConstructor.cpp b/WebCore/bindings/js/JSAudioConstructor.cpp new file mode 100644 index 0000000..1efb0d8 --- /dev/null +++ b/WebCore/bindings/js/JSAudioConstructor.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(VIDEO) +#include "JSAudioConstructor.h" + +#include "Document.h" +#include "HTMLAudioElement.h" +#include "JSHTMLAudioElement.h" +#include "Text.h" + +using namespace KJS; + +namespace WebCore { + +JSAudioConstructor::JSAudioConstructor(ExecState* exec, Document* d) + : DOMObject(exec->lexicalGlobalObject()->objectPrototype()) + , m_doc(d) +{ + putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum); +} + +bool JSAudioConstructor::implementsConstruct() const +{ + return true; +} + +JSObject* JSAudioConstructor::construct(ExecState* exec, const List& args) +{ + int exception = 0; + RefPtr<Element> el(m_doc->createElement("audio", exception)); + HTMLAudioElement* audio = 0; + if (el && !exception) { + audio = static_cast<HTMLAudioElement*>(el.get()); + int sz = args.size(); + if (sz > 0) { + audio->setSrc(args[0]->toString(exec)); + audio->scheduleLoad(); + } + } + + setDOMException(exec, exception); + return static_cast<JSObject*>(toJS(exec, audio)); +} + +} +#endif diff --git a/WebCore/bindings/js/JSAudioConstructor.h b/WebCore/bindings/js/JSAudioConstructor.h new file mode 100644 index 0000000..3bfd857 --- /dev/null +++ b/WebCore/bindings/js/JSAudioConstructor.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSAudioConstructor_h +#define JSAudioConstructor_h + +#if ENABLE(VIDEO) + +#include "kjs_binding.h" +#include <wtf/RefPtr.h> + +namespace WebCore { + + class JSAudioConstructor : public DOMObject { + public: + JSAudioConstructor(KJS::ExecState*, Document*); + virtual bool implementsConstruct() const; + virtual KJS::JSObject *construct(KJS::ExecState*, const KJS::List& args); + private: + RefPtr<Document> m_doc; + }; + +} + +#endif +#endif diff --git a/WebCore/bindings/js/JSCSSRuleCustom.cpp b/WebCore/bindings/js/JSCSSRuleCustom.cpp new file mode 100644 index 0000000..44a52a6 --- /dev/null +++ b/WebCore/bindings/js/JSCSSRuleCustom.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSCSSRule.h" + +#include "CSSCharsetRule.h" +#include "CSSFontFaceRule.h" +#include "CSSImportRule.h" +#include "CSSMediaRule.h" +#include "CSSPageRule.h" +#include "CSSStyleRule.h" +#include "JSCSSCharsetRule.h" +#include "JSCSSFontFaceRule.h" +#include "JSCSSImportRule.h" +#include "JSCSSMediaRule.h" +#include "JSCSSPageRule.h" +#include "JSCSSStyleRule.h" + +using namespace KJS; + +namespace WebCore { + +JSValue* toJS(ExecState* exec, CSSRule* rule) +{ + if (!rule) + return jsNull(); + + DOMObject* ret = ScriptInterpreter::getDOMObject(rule); + + if (ret) + return ret; + + switch (rule->type()) { + case CSSRule::STYLE_RULE: + ret = new JSCSSStyleRule(JSCSSRulePrototype::self(exec), static_cast<CSSStyleRule*>(rule)); + break; + case CSSRule::MEDIA_RULE: + ret = new JSCSSMediaRule(JSCSSMediaRulePrototype::self(exec), static_cast<CSSMediaRule*>(rule)); + break; + case CSSRule::FONT_FACE_RULE: + ret = new JSCSSFontFaceRule(JSCSSFontFaceRulePrototype::self(exec), static_cast<CSSFontFaceRule*>(rule)); + break; + case CSSRule::PAGE_RULE: + ret = new JSCSSPageRule(JSCSSPageRulePrototype::self(exec), static_cast<CSSPageRule*>(rule)); + break; + case CSSRule::IMPORT_RULE: + ret = new JSCSSImportRule(JSCSSImportRulePrototype::self(exec), static_cast<CSSImportRule*>(rule)); + break; + case CSSRule::CHARSET_RULE: + ret = new JSCSSCharsetRule(JSCSSCharsetRulePrototype::self(exec), static_cast<CSSCharsetRule*>(rule)); + break; + default: + ret = new JSCSSRule(JSCSSRulePrototype::self(exec), rule); + break; + } + + ScriptInterpreter::putDOMObject(rule, ret); + return ret; +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp b/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp new file mode 100644 index 0000000..0723410 --- /dev/null +++ b/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSCSSStyleDeclaration.h" + +#include "AtomicString.h" +#include "CSSPrimitiveValue.h" +#include "CSSStyleDeclaration.h" +#include "CSSValue.h" +#include "PlatformString.h" +#include <kjs/string_object.h> +#include <wtf/ASCIICType.h> + +using namespace KJS; +using namespace WTF; + +namespace WebCore { + +// Check for a CSS prefix. +// Passed prefix is all lowercase. +// First characters of property name may be upper or lowercase. +// Other characters in the prefix within the property name must be lowercase. +// The prefix within the property name must be followed by a capital letter. +static bool hasCSSPropertyNamePrefix(const Identifier& propertyName, const char* prefix) +{ +#ifndef NDEBUG + ASSERT(*prefix); + for (const char* p = prefix; *p; ++p) + ASSERT(isASCIILower(*p)); +#endif + + unsigned length = propertyName.size(); + ASSERT(length); + + if (toASCIILower(propertyName.data()[0].unicode()) != prefix[0]) + return false; + + for (unsigned i = 1; i < length; ++i) { + if (!prefix[i]) + return isASCIIUpper(propertyName.data()[i].unicode()); + if (propertyName.data()[0].unicode() != prefix[0]) + return false; + } + return false; +} + +static String cssPropertyName(const Identifier& propertyName, bool* hadPixelOrPosPrefix = 0) +{ + if (hadPixelOrPosPrefix) + *hadPixelOrPosPrefix = false; + + unsigned length = propertyName.size(); + if (!length) + return String(); + + Vector< ::UChar> name; + name.reserveCapacity(length); + + unsigned i = 0; + + if (hasCSSPropertyNamePrefix(propertyName, "css")) + i += 3; + else if (hasCSSPropertyNamePrefix(propertyName, "pixel")) { + i += 5; + if (hadPixelOrPosPrefix) + *hadPixelOrPosPrefix = true; + } else if (hasCSSPropertyNamePrefix(propertyName, "pos")) { + i += 3; + if (hadPixelOrPosPrefix) + *hadPixelOrPosPrefix = true; + } else if (hasCSSPropertyNamePrefix(propertyName, "webkit") + || hasCSSPropertyNamePrefix(propertyName, "khtml") + || hasCSSPropertyNamePrefix(propertyName, "apple")) + name.append('-'); + + name.append(toASCIILower(propertyName.data()[i++].unicode())); + + for (; i < length; ++i) { + ::UChar c = propertyName.data()[i].unicode(); + if (!isASCIIUpper(c)) + name.append(c); + else { + name.append('-'); + name.append(toASCIILower(c)); + } + } + + return String::adopt(name); +} + +static bool isCSSPropertyName(const Identifier& propertyName) +{ + return CSSStyleDeclaration::isPropertyName(cssPropertyName(propertyName)); +} + +bool JSCSSStyleDeclaration::canGetItemsForName(ExecState*, CSSStyleDeclaration*, const Identifier& propertyName) +{ + return isCSSPropertyName(propertyName); +} + +// FIXME: You can get these properties, and set them (see customPut below), +// but you should also be able to enumerate them. +JSValue* JSCSSStyleDeclaration::nameGetter(ExecState* exec, JSObject* originalObject, + const Identifier& propertyName, const PropertySlot& slot) +{ + JSCSSStyleDeclaration* thisObj = static_cast<JSCSSStyleDeclaration*>(slot.slotBase()); + + // Set up pixelOrPos boolean to handle the fact that + // pixelTop returns "CSS Top" as number value in unit pixels + // posTop returns "CSS top" as number value in unit pixels _if_ its a + // positioned element. if it is not a positioned element, return 0 + // from MSIE documentation FIXME: IMPLEMENT THAT (Dirk) + bool pixelOrPos; + String prop = cssPropertyName(propertyName, &pixelOrPos); + RefPtr<CSSValue> v = thisObj->impl()->getPropertyCSSValue(prop); + if (v) { + if (pixelOrPos && v->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE) + return jsNumber(static_pointer_cast<CSSPrimitiveValue>(v)->getFloatValue(CSSPrimitiveValue::CSS_PX)); + return jsStringOrNull(v->cssText()); + } + + // If the property is a shorthand property (such as "padding"), + // it can only be accessed using getPropertyValue. + + // Make the SVG 'filter' attribute undetectable, to avoid confusion with the IE 'filter' attribute. + if (propertyName == "filter") + return new StringInstanceThatMasqueradesAsUndefined(exec->lexicalGlobalObject()->stringPrototype(), + thisObj->impl()->getPropertyValue(prop)); + + return jsString(thisObj->impl()->getPropertyValue(prop)); +} + + +bool JSCSSStyleDeclaration::customPut(ExecState* exec, const Identifier& propertyName, JSValue* value) +{ + if (!isCSSPropertyName(propertyName)) + return false; + + DOMExceptionTranslator exception(exec); + bool pixelOrPos; + String prop = cssPropertyName(propertyName, &pixelOrPos); + String propValue = valueToStringWithNullCheck(exec, value); + if (pixelOrPos) + propValue += "px"; + impl()->setProperty(prop, propValue, exception); + return true; +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSCSSValueCustom.cpp b/WebCore/bindings/js/JSCSSValueCustom.cpp new file mode 100644 index 0000000..88147d7 --- /dev/null +++ b/WebCore/bindings/js/JSCSSValueCustom.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSCSSValue.h" + +#include "CSSPrimitiveValue.h" +#include "CSSValueList.h" +#include "JSCSSPrimitiveValue.h" +#include "JSCSSValueList.h" + +#if ENABLE(SVG) +#include "JSSVGColor.h" +#include "JSSVGPaint.h" +#include "SVGColor.h" +#include "SVGPaint.h" +#endif + +using namespace KJS; + +namespace WebCore { + +JSValue* toJS(ExecState* exec, CSSValue* value) +{ + if (!value) + return jsNull(); + + DOMObject* ret = ScriptInterpreter::getDOMObject(value); + + if (ret) + return ret; + + if (value->isValueList()) + ret = new JSCSSValueList(JSCSSValueListPrototype::self(exec), static_cast<CSSValueList*>(value)); +#if ENABLE(SVG) + else if (value->isSVGPaint()) + ret = new JSSVGPaint(JSSVGPaintPrototype::self(exec), static_cast<SVGPaint*>(value)); + else if (value->isSVGColor()) + ret = new JSSVGColor(JSSVGColorPrototype::self(exec), static_cast<SVGColor*>(value)); +#endif + else if (value->isPrimitiveValue()) + ret = new JSCSSPrimitiveValue(JSCSSPrimitiveValuePrototype::self(exec), static_cast<CSSPrimitiveValue*>(value)); + else + ret = new JSCSSValue(JSCSSValuePrototype::self(exec), value); + + ScriptInterpreter::putDOMObject(value, ret); + return ret; +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSCanvasPixelArrayCustom.cpp b/WebCore/bindings/js/JSCanvasPixelArrayCustom.cpp new file mode 100644 index 0000000..23e6afd --- /dev/null +++ b/WebCore/bindings/js/JSCanvasPixelArrayCustom.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSCanvasPixelArray.h" + +#include "CanvasPixelArray.h" + +using namespace KJS; + +namespace WebCore { + +JSValue* JSCanvasPixelArray::indexGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot) +{ + CanvasPixelArray* array = static_cast<JSCanvasPixelArray*>(slot.slotBase())->impl(); + unsigned index = slot.index(); + unsigned char result; + if (!array->get(index, result)) + return jsUndefined(); + return jsNumber(result); +} + +void JSCanvasPixelArray::indexSetter(ExecState* exec, unsigned index, JSValue* value) +{ + double pixelValue = value->toNumber(exec); + if (exec->hadException()) + return; + m_impl->set(index, pixelValue); +} + +JSValue* toJS(ExecState* exec, CanvasPixelArray* pixels) +{ + if (!pixels) + return jsNull(); + + DOMObject* ret = ScriptInterpreter::getDOMObject(pixels); + if (ret) + return ret; + + ret = new JSCanvasPixelArray(JSCanvasPixelArrayPrototype::self(exec), pixels); + + Collector::reportExtraMemoryCost(pixels->length()); + + ScriptInterpreter::putDOMObject(pixels, ret); + + return ret; +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp b/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp new file mode 100644 index 0000000..c5256d9 --- /dev/null +++ b/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp @@ -0,0 +1,356 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "JSCanvasRenderingContext2D.h" + +#include "CanvasGradient.h" +#include "CanvasPattern.h" +#include "CanvasRenderingContext2D.h" +#include "CanvasStyle.h" +#include "ExceptionCode.h" +#include "FloatRect.h" +#include "HTMLCanvasElement.h" +#include "HTMLImageElement.h" +#include "ImageData.h" +#include "JSCanvasGradient.h" +#include "JSCanvasPattern.h" +#include "JSHTMLCanvasElement.h" +#include "JSHTMLImageElement.h" +#include "JSImageData.h" +#include "kjs_html.h" + +using namespace KJS; + +namespace WebCore { + +static JSValue* toJS(ExecState* exec, CanvasStyle* style) +{ + if (style->gradient()) + return toJS(exec, style->gradient()); + if (style->pattern()) + return toJS(exec, style->pattern()); + return jsString(style->color()); +} + +static PassRefPtr<CanvasStyle> toHTMLCanvasStyle(ExecState* exec, JSValue* value) +{ + if (value->isString()) + return new CanvasStyle(value->toString(exec)); + if (!value->isObject()) + return 0; + JSObject* object = static_cast<JSObject*>(value); + if (object->inherits(&JSCanvasGradient::info)) + return new CanvasStyle(static_cast<JSCanvasGradient*>(object)->impl()); + if (object->inherits(&JSCanvasPattern::info)) + return new CanvasStyle(static_cast<JSCanvasPattern*>(object)->impl()); + return 0; +} + +JSValue* JSCanvasRenderingContext2D::strokeStyle(ExecState* exec) const +{ + return toJS(exec, impl()->strokeStyle()); +} + +void JSCanvasRenderingContext2D::setStrokeStyle(ExecState* exec, JSValue* value) +{ + impl()->setStrokeStyle(toHTMLCanvasStyle(exec, value)); +} + +JSValue* JSCanvasRenderingContext2D::fillStyle(ExecState* exec) const +{ + return toJS(exec, impl()->fillStyle()); +} + +void JSCanvasRenderingContext2D::setFillStyle(ExecState* exec, JSValue* value) +{ + impl()->setFillStyle(toHTMLCanvasStyle(exec, value)); +} + +JSValue* JSCanvasRenderingContext2D::setFillColor(ExecState* exec, const List& args) +{ + CanvasRenderingContext2D* context = impl(); + + // string arg = named color + // number arg = gray color + // string arg, number arg = named color, alpha + // number arg, number arg = gray color, alpha + // 4 args = r, g, b, a + // 5 args = c, m, y, k, a + switch (args.size()) { + case 1: + if (args[0]->isString()) + context->setFillColor(args[0]->toString(exec)); + else + context->setFillColor(args[0]->toFloat(exec)); + break; + case 2: + if (args[0]->isString()) + context->setFillColor(args[0]->toString(exec), args[1]->toFloat(exec)); + else + context->setFillColor(args[0]->toFloat(exec), args[1]->toFloat(exec)); + break; + case 4: + context->setFillColor(args[0]->toFloat(exec), args[1]->toFloat(exec), + args[2]->toFloat(exec), args[3]->toFloat(exec)); + break; + case 5: + context->setFillColor(args[0]->toFloat(exec), args[1]->toFloat(exec), + args[2]->toFloat(exec), args[3]->toFloat(exec), args[4]->toFloat(exec)); + break; + default: + return throwError(exec, SyntaxError); + } + return jsUndefined(); +} + +JSValue* JSCanvasRenderingContext2D::setStrokeColor(ExecState* exec, const List& args) +{ + CanvasRenderingContext2D* context = impl(); + + // string arg = named color + // number arg = gray color + // string arg, number arg = named color, alpha + // number arg, number arg = gray color, alpha + // 4 args = r, g, b, a + // 5 args = c, m, y, k, a + switch (args.size()) { + case 1: + if (args[0]->isString()) + context->setStrokeColor(args[0]->toString(exec)); + else + context->setStrokeColor(args[0]->toFloat(exec)); + break; + case 2: + if (args[0]->isString()) + context->setStrokeColor(args[0]->toString(exec), args[1]->toFloat(exec)); + else + context->setStrokeColor(args[0]->toFloat(exec), args[1]->toFloat(exec)); + break; + case 4: + context->setStrokeColor(args[0]->toFloat(exec), args[1]->toFloat(exec), + args[2]->toFloat(exec), args[3]->toFloat(exec)); + break; + case 5: + context->setStrokeColor(args[0]->toFloat(exec), args[1]->toFloat(exec), + args[2]->toFloat(exec), args[3]->toFloat(exec), args[4]->toFloat(exec)); + break; + default: + return throwError(exec, SyntaxError); + } + + return jsUndefined(); +} + +JSValue* JSCanvasRenderingContext2D::strokeRect(ExecState* exec, const List& args) +{ + CanvasRenderingContext2D* context = impl(); + ExceptionCode ec; + + if (args.size() <= 4) + context->strokeRect(args[0]->toFloat(exec), args[1]->toFloat(exec), + args[2]->toFloat(exec), args[3]->toFloat(exec), ec); + else + context->strokeRect(args[0]->toFloat(exec), args[1]->toFloat(exec), + args[2]->toFloat(exec), args[3]->toFloat(exec), args[4]->toFloat(exec), ec); + setDOMException(exec, ec); + + return jsUndefined(); +} + +JSValue* JSCanvasRenderingContext2D::drawImage(ExecState* exec, const List& args) +{ + CanvasRenderingContext2D* context = impl(); + + // DrawImage has three variants: + // drawImage(img, dx, dy) + // drawImage(img, dx, dy, dw, dh) + // drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh) + // Composite operation is specified with globalCompositeOperation. + // The img parameter can be a <img> or <canvas> element. + JSValue* value = args[0]; + if (!value->isObject()) + return throwError(exec, TypeError); + JSObject* o = static_cast<JSObject*>(value); + + ExceptionCode ec = 0; + if (o->inherits(&JSHTMLImageElement::info)) { + HTMLImageElement* imgElt = static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(args[0])->impl()); + switch (args.size()) { + case 3: + context->drawImage(imgElt, args[1]->toFloat(exec), args[2]->toFloat(exec)); + break; + case 5: + context->drawImage(imgElt, args[1]->toFloat(exec), args[2]->toFloat(exec), + args[3]->toFloat(exec), args[4]->toFloat(exec), ec); + setDOMException(exec, ec); + break; + case 9: + context->drawImage(imgElt, FloatRect(args[1]->toFloat(exec), args[2]->toFloat(exec), + args[3]->toFloat(exec), args[4]->toFloat(exec)), + FloatRect(args[5]->toFloat(exec), args[6]->toFloat(exec), + args[7]->toFloat(exec), args[8]->toFloat(exec)), ec); + setDOMException(exec, ec); + break; + default: + return throwError(exec, SyntaxError); + } + } else if (o->inherits(&JSHTMLCanvasElement::info)) { + HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLElement*>(args[0])->impl()); + switch (args.size()) { + case 3: + context->drawImage(canvas, args[1]->toFloat(exec), args[2]->toFloat(exec)); + break; + case 5: + context->drawImage(canvas, args[1]->toFloat(exec), args[2]->toFloat(exec), + args[3]->toFloat(exec), args[4]->toFloat(exec), ec); + setDOMException(exec, ec); + break; + case 9: + context->drawImage(canvas, FloatRect(args[1]->toFloat(exec), args[2]->toFloat(exec), + args[3]->toFloat(exec), args[4]->toFloat(exec)), + FloatRect(args[5]->toFloat(exec), args[6]->toFloat(exec), + args[7]->toFloat(exec), args[8]->toFloat(exec)), ec); + setDOMException(exec, ec); + break; + default: + return throwError(exec, SyntaxError); + } + } else { + setDOMException(exec, TYPE_MISMATCH_ERR); + return 0; + } + + return jsUndefined(); +} + +JSValue* JSCanvasRenderingContext2D::drawImageFromRect(ExecState* exec, const List& args) +{ + CanvasRenderingContext2D* context = impl(); + + JSValue* value = args[0]; + if (!value->isObject()) + return throwError(exec, TypeError); + JSObject* o = static_cast<JSObject*>(value); + + if (!o->inherits(&JSHTMLImageElement::info)) + return throwError(exec, TypeError); + context->drawImageFromRect(static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(args[0])->impl()), + args[1]->toFloat(exec), args[2]->toFloat(exec), + args[3]->toFloat(exec), args[4]->toFloat(exec), + args[5]->toFloat(exec), args[6]->toFloat(exec), + args[7]->toFloat(exec), args[8]->toFloat(exec), + args[9]->toString(exec)); + return jsUndefined(); +} + +JSValue* JSCanvasRenderingContext2D::setShadow(ExecState* exec, const List& args) +{ + CanvasRenderingContext2D* context = impl(); + + switch (args.size()) { + case 3: + context->setShadow(args[0]->toFloat(exec), args[1]->toFloat(exec), + args[2]->toFloat(exec)); + break; + case 4: + if (args[3]->isString()) + context->setShadow(args[0]->toFloat(exec), args[1]->toFloat(exec), + args[2]->toFloat(exec), args[3]->toString(exec)); + else + context->setShadow(args[0]->toFloat(exec), args[1]->toFloat(exec), + args[2]->toFloat(exec), args[3]->toFloat(exec)); + break; + case 5: + if (args[3]->isString()) + context->setShadow(args[0]->toFloat(exec), args[1]->toFloat(exec), + args[2]->toFloat(exec), args[3]->toString(exec), + args[4]->toFloat(exec)); + else + context->setShadow(args[0]->toFloat(exec), args[1]->toFloat(exec), + args[2]->toFloat(exec), args[3]->toFloat(exec), + args[4]->toFloat(exec)); + break; + case 7: + context->setShadow(args[0]->toFloat(exec), args[1]->toFloat(exec), + args[2]->toFloat(exec), args[3]->toFloat(exec), + args[4]->toFloat(exec), args[5]->toFloat(exec), + args[6]->toFloat(exec)); + break; + case 8: + context->setShadow(args[0]->toFloat(exec), args[1]->toFloat(exec), + args[2]->toFloat(exec), args[3]->toFloat(exec), + args[4]->toFloat(exec), args[5]->toFloat(exec), + args[6]->toFloat(exec), args[7]->toFloat(exec)); + break; + default: + return throwError(exec, SyntaxError); + } + + return jsUndefined(); +} + +JSValue* JSCanvasRenderingContext2D::createPattern(ExecState* exec, const List& args) +{ + CanvasRenderingContext2D* context = impl(); + + JSValue* value = args[0]; + if (!value->isObject()) + return throwError(exec, TypeError); + JSObject* o = static_cast<JSObject*>(value); + + if (o->inherits(&JSHTMLImageElement::info)) { + ExceptionCode ec; + JSValue* pattern = toJS(exec, + context->createPattern(static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(args[0])->impl()), + args[1]->toString(exec), ec).get()); + setDOMException(exec, ec); + return pattern; + } + if (o->inherits(&JSHTMLCanvasElement::info)) { + ExceptionCode ec; + JSValue* pattern = toJS(exec, + context->createPattern(static_cast<HTMLCanvasElement*>(static_cast<JSHTMLElement*>(args[0])->impl()), + args[1]->toString(exec), ec).get()); + setDOMException(exec, ec); + return pattern; + } + setDOMException(exec, TYPE_MISMATCH_ERR); + return 0; +} + +JSValue* JSCanvasRenderingContext2D::putImageData(ExecState* exec, const List& args) +{ + // putImageData has two variants + // putImageData(ImageData, x, y) + // putImageData(ImageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight) + CanvasRenderingContext2D* context = impl(); + + ExceptionCode ec = 0; + if (args.size() >= 7) + context->putImageData(toImageData(args[0]), args[1]->toFloat(exec), args[2]->toFloat(exec), + args[3]->toFloat(exec), args[4]->toFloat(exec), args[5]->toFloat(exec), args[6]->toFloat(exec), ec); + else + context->putImageData(toImageData(args[0]), args[1]->toFloat(exec), args[2]->toFloat(exec), ec); + + setDOMException(exec, ec); + return jsUndefined(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp b/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp new file mode 100644 index 0000000..7adab5f --- /dev/null +++ b/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSCustomSQLStatementCallback.h" + +#include "CString.h" +#include "Frame.h" +#include "kjs_proxy.h" +#include "JSSQLResultSet.h" +#include "JSSQLTransaction.h" +#include "Page.h" + +namespace WebCore { + +using namespace KJS; + +JSCustomSQLStatementCallback::JSCustomSQLStatementCallback(JSObject* callback, Frame* frame) + : m_callback(callback) + , m_frame(frame) +{ +} + +void JSCustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLResultSet* resultSet, bool& raisedException) +{ + ASSERT(m_callback); + ASSERT(m_frame); + + if (!m_frame->scriptProxy()->isEnabled()) + return; + + JSGlobalObject* globalObject = m_frame->scriptProxy()->globalObject(); + ExecState* exec = globalObject->globalExec(); + + KJS::JSLock lock; + + JSValue* handleEventFuncValue = m_callback->get(exec, "handleEvent"); + JSObject* handleEventFunc = 0; + if (handleEventFuncValue->isObject()) { + handleEventFunc = static_cast<JSObject*>(handleEventFuncValue); + if (!handleEventFunc->implementsCall()) + handleEventFunc = 0; + } + + if (!handleEventFunc && !m_callback->implementsCall()) { + // FIXME: Should an exception be thrown here? + return; + } + + RefPtr<JSCustomSQLStatementCallback> protect(this); + + List args; + args.append(toJS(exec, transaction)); + args.append(toJS(exec, resultSet)); + + globalObject->startTimeoutCheck(); + if (handleEventFunc) + handleEventFunc->call(exec, m_callback, args); + else + m_callback->call(exec, m_callback, args); + globalObject->stopTimeoutCheck(); + + if (exec->hadException()) { + JSObject* exception = exec->exception()->toObject(exec); + String message = exception->get(exec, exec->propertyNames().message)->toString(exec); + int lineNumber = exception->get(exec, "line")->toInt32(exec); + String sourceURL = exception->get(exec, "sourceURL")->toString(exec); + if (Interpreter::shouldPrintExceptions()) + printf("SQLStatementCallback: %s\n", message.utf8().data()); + if (Page* page = m_frame->page()) + page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, message, lineNumber, sourceURL); + + raisedException = true; + + exec->clearException(); + } + + Document::updateDocumentsRendering(); +} + +} diff --git a/WebCore/bindings/js/JSCustomSQLStatementCallback.h b/WebCore/bindings/js/JSCustomSQLStatementCallback.h new file mode 100644 index 0000000..27bca7b --- /dev/null +++ b/WebCore/bindings/js/JSCustomSQLStatementCallback.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSCustomSQLStatementCallback_h +#define JSCustomSQLStatementCallback_h + +#include "SQLStatementCallback.h" + +#include <kjs/object.h> +#include <kjs/protect.h> +#include <wtf/Forward.h> + +namespace KJS { + class JSObject; +} + +namespace WebCore { + +class Frame; +class SQLResultSet; + +class JSCustomSQLStatementCallback : public SQLStatementCallback { +public: + JSCustomSQLStatementCallback(KJS::JSObject* callback, Frame*); + + virtual void handleEvent(SQLTransaction*, SQLResultSet*, bool& raisedException); +private: + KJS::ProtectedPtr<KJS::JSObject> m_callback; + RefPtr<Frame> m_frame; +}; + +} + +#endif // JSCustomSQLStatementCallback_h diff --git a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp new file mode 100644 index 0000000..615082d --- /dev/null +++ b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSCustomSQLStatementErrorCallback.h" + +#include "CString.h" +#include "Frame.h" +#include "kjs_proxy.h" +#include "JSSQLError.h" +#include "JSSQLTransaction.h" +#include "Page.h" + +namespace WebCore { + +using namespace KJS; + +JSCustomSQLStatementErrorCallback::JSCustomSQLStatementErrorCallback(JSObject* callback, Frame* frame) + : m_callback(callback) + , m_frame(frame) +{ +} + +bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, SQLError* error) +{ + ASSERT(m_callback); + ASSERT(m_frame); + + if (!m_frame->scriptProxy()->isEnabled()) + return true; + + JSGlobalObject* globalObject = m_frame->scriptProxy()->globalObject(); + ExecState* exec = globalObject->globalExec(); + + KJS::JSLock lock; + + JSValue* handleEventFuncValue = m_callback->get(exec, "handleEvent"); + JSObject* handleEventFunc = 0; + if (handleEventFuncValue->isObject()) { + handleEventFunc = static_cast<JSObject*>(handleEventFuncValue); + if (!handleEventFunc->implementsCall()) + handleEventFunc = 0; + } + + if (!handleEventFunc && !m_callback->implementsCall()) { + // FIXME: Should an exception be thrown here? + return true; + } + + RefPtr<JSCustomSQLStatementErrorCallback> protect(this); + + List args; + args.append(toJS(exec, transaction)); + args.append(toJS(exec, error)); + + JSValue *result; + globalObject->startTimeoutCheck(); + if (handleEventFunc) + result = handleEventFunc->call(exec, m_callback, args); + else + result = m_callback->call(exec, m_callback, args); + globalObject->stopTimeoutCheck(); + + if (exec->hadException()) { + JSObject* exception = exec->exception()->toObject(exec); + String message = exception->get(exec, exec->propertyNames().message)->toString(exec); + int lineNumber = exception->get(exec, "line")->toInt32(exec); + String sourceURL = exception->get(exec, "sourceURL")->toString(exec); + if (Interpreter::shouldPrintExceptions()) + printf("SQLStatementErrorCallback: %s\n", message.utf8().data()); + if (Page* page = m_frame->page()) + page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, message, lineNumber, sourceURL); + exec->clearException(); + + // The spec says: + // "If the error callback returns false, then move on to the next statement..." + // "Otherwise, the error callback did not return false, or there was no error callback" + // Therefore an exception and returning true are the same thing - so, return true on an exception + return true; + } + + Document::updateDocumentsRendering(); + + return result->toBoolean(exec); +} + +} diff --git a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.h b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.h new file mode 100644 index 0000000..7bc40c6 --- /dev/null +++ b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSCustomSQLStatementErrorCallback_h +#define JSCustomSQLStatementErrorCallback_h + +#include "SQLStatementErrorCallback.h" + +#include <kjs/object.h> +#include <kjs/protect.h> +#include <wtf/Forward.h> + +namespace KJS { + class JSObject; +} + +namespace WebCore { + +class Frame; +class SQLError; + +class JSCustomSQLStatementErrorCallback : public SQLStatementErrorCallback { +public: + JSCustomSQLStatementErrorCallback(KJS::JSObject* callback, Frame*); + + virtual bool handleEvent(SQLTransaction*, SQLError*); +private: + KJS::ProtectedPtr<KJS::JSObject> m_callback; + RefPtr<Frame> m_frame; +}; + +} + +#endif // JSCustomSQLStatementErrorCallback_h + diff --git a/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp b/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp new file mode 100644 index 0000000..cd50ebd --- /dev/null +++ b/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSCustomSQLTransactionCallback.h" + +#include "CString.h" +#include "Frame.h" +#include "Logging.h" +#include "MainThread.h" +#include "kjs_proxy.h" +#include "JSSQLTransaction.h" +#include "Page.h" + +namespace WebCore { + +using namespace KJS; + +#ifndef NDEBUG + +WTFLogChannel LogWebCoreSQLLeaks = { 0x00000000, "", WTFLogChannelOn }; + +struct JSCustomSQLTransactionCallbackCounter { + static int count; + ~JSCustomSQLTransactionCallbackCounter() + { + if (count) + LOG(WebCoreSQLLeaks, "LEAK: %d JSCustomSQLTransactionCallback\n", count); + } +}; + +int JSCustomSQLTransactionCallbackCounter::count = 0; +static JSCustomSQLTransactionCallbackCounter counter; + +#endif + +// We have to clean up the data on the main thread for two reasons: +// +// 1) Can't deref a Frame on a non-main thread. +// 2) Unprotecting the JSObject on a non-main thread would register that thread +// for JavaScript garbage collection, which could unnecessarily slow things down. + +class JSCustomSQLTransactionCallback::Data { +public: + Data(JSObject* callback, Frame* frame) : m_callback(callback), m_frame(frame) { } + JSObject* callback() { return m_callback; } + Frame* frame() { return m_frame.get(); } + +private: + ProtectedPtr<JSObject> m_callback; + RefPtr<Frame> m_frame; +}; + +JSCustomSQLTransactionCallback::JSCustomSQLTransactionCallback(JSObject* callback, Frame* frame) + : m_data(new Data(callback, frame)) +{ +#ifndef NDEBUG + ++JSCustomSQLTransactionCallbackCounter::count; +#endif +} + +void JSCustomSQLTransactionCallback::deleteData(void* context) +{ + delete static_cast<Data*>(context); +} + +JSCustomSQLTransactionCallback::~JSCustomSQLTransactionCallback() +{ + callOnMainThread(deleteData, m_data); +#ifndef NDEBUG + m_data = 0; + --JSCustomSQLTransactionCallbackCounter::count; +#endif +} + +void JSCustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bool& raisedException) +{ + ASSERT(m_data); + ASSERT(m_data->callback()); + ASSERT(m_data->frame()); + + if (!m_data->frame()->scriptProxy()->isEnabled()) + return; + + JSGlobalObject* globalObject = m_data->frame()->scriptProxy()->globalObject(); + ExecState* exec = globalObject->globalExec(); + + KJS::JSLock lock; + + JSValue* handleEventFuncValue = m_data->callback()->get(exec, "handleEvent"); + JSObject* handleEventFunc = 0; + if (handleEventFuncValue->isObject()) { + handleEventFunc = static_cast<JSObject*>(handleEventFuncValue); + if (!handleEventFunc->implementsCall()) + handleEventFunc = 0; + } + + if (!handleEventFunc && !m_data->callback()->implementsCall()) { + // FIXME: Should an exception be thrown here? + return; + } + + RefPtr<JSCustomSQLTransactionCallback> protect(this); + + List args; + args.append(toJS(exec, transaction)); + + globalObject->startTimeoutCheck(); + if (handleEventFunc) + handleEventFunc->call(exec, m_data->callback(), args); + else + m_data->callback()->call(exec, m_data->callback(), args); + globalObject->stopTimeoutCheck(); + + if (exec->hadException()) { + JSObject* exception = exec->exception()->toObject(exec); + String message = exception->get(exec, exec->propertyNames().message)->toString(exec); + int lineNumber = exception->get(exec, "line")->toInt32(exec); + String sourceURL = exception->get(exec, "sourceURL")->toString(exec); + if (Interpreter::shouldPrintExceptions()) + printf("SQLTransactionCallback: %s\n", message.utf8().data()); + if (Page* page = m_data->frame()->page()) + page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, message, lineNumber, sourceURL); + exec->clearException(); + + raisedException = true; + } + + Document::updateDocumentsRendering(); +} + +} diff --git a/WebCore/bindings/js/JSCustomSQLTransactionCallback.h b/WebCore/bindings/js/JSCustomSQLTransactionCallback.h new file mode 100644 index 0000000..aa31d50 --- /dev/null +++ b/WebCore/bindings/js/JSCustomSQLTransactionCallback.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSCustomSQLTransactionCallback_h +#define JSCustomSQLTransactionCallback_h + +#include "SQLTransactionCallback.h" + +namespace KJS { + class JSObject; +} + +namespace WebCore { + +class Frame; + +class JSCustomSQLTransactionCallback : public SQLTransactionCallback { +public: + JSCustomSQLTransactionCallback(KJS::JSObject* callback, Frame*); + virtual ~JSCustomSQLTransactionCallback(); + + virtual void handleEvent(SQLTransaction*, bool& raisedException); + +private: + static void deleteData(void*); + + class Data; + Data* m_data; +}; + +} + +#endif // JSCustomSQLTransactionCallback_h diff --git a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp new file mode 100644 index 0000000..ff4d1c1 --- /dev/null +++ b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSCustomSQLTransactionErrorCallback.h" + +#include "CString.h" +#include "Frame.h" +#include "kjs_proxy.h" +#include "JSSQLError.h" +#include "Page.h" + +namespace WebCore { + +using namespace KJS; + +JSCustomSQLTransactionErrorCallback::JSCustomSQLTransactionErrorCallback(JSObject* callback, Frame* frame) + : m_callback(callback) + , m_frame(frame) +{ +} + +bool JSCustomSQLTransactionErrorCallback::handleEvent(SQLError* error) +{ + ASSERT(m_callback); + ASSERT(m_frame); + + if (!m_frame->scriptProxy()->isEnabled()) + return true; + + JSGlobalObject* globalObject = m_frame->scriptProxy()->globalObject(); + ExecState* exec = globalObject->globalExec(); + + KJS::JSLock lock; + + JSValue* handleEventFuncValue = m_callback->get(exec, "handleEvent"); + JSObject* handleEventFunc = 0; + if (handleEventFuncValue->isObject()) { + handleEventFunc = static_cast<JSObject*>(handleEventFuncValue); + if (!handleEventFunc->implementsCall()) + handleEventFunc = 0; + } + + if (!handleEventFunc && !m_callback->implementsCall()) { + // FIXME: Should an exception be thrown here? + return true; + } + + RefPtr<JSCustomSQLTransactionErrorCallback> protect(this); + + List args; + args.append(toJS(exec, error)); + + JSValue *result; + globalObject->startTimeoutCheck(); + if (handleEventFunc) + result = handleEventFunc->call(exec, m_callback, args); + else + result = m_callback->call(exec, m_callback, args); + globalObject->stopTimeoutCheck(); + + if (exec->hadException()) { + JSObject* exception = exec->exception()->toObject(exec); + String message = exception->get(exec, exec->propertyNames().message)->toString(exec); + int lineNumber = exception->get(exec, "line")->toInt32(exec); + String sourceURL = exception->get(exec, "sourceURL")->toString(exec); + if (Interpreter::shouldPrintExceptions()) + printf("SQLTransactionErrorCallback: %s\n", message.utf8().data()); + if (Page* page = m_frame->page()) + page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, message, lineNumber, sourceURL); + exec->clearException(); + } + + Document::updateDocumentsRendering(); + + return result->toBoolean(exec); +} + +} diff --git a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.h b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.h new file mode 100644 index 0000000..6b079c4 --- /dev/null +++ b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSCustomSQLTransactionErrorCallback_h +#define JSCustomSQLTransactionErrorCallback_h + +#include "SQLTransactionErrorCallback.h" + +#include <kjs/object.h> +#include <kjs/protect.h> +#include <wtf/Forward.h> + +namespace KJS { + class JSObject; +} + +namespace WebCore { + +class Frame; +class SQLError; + +class JSCustomSQLTransactionErrorCallback : public SQLTransactionErrorCallback { +public: + JSCustomSQLTransactionErrorCallback(KJS::JSObject* callback, Frame*); + + virtual bool handleEvent(SQLError*); +private: + KJS::ProtectedPtr<KJS::JSObject> m_callback; + RefPtr<Frame> m_frame; +}; + +} + +#endif // JSCustomSQLTransactionErrorCallback_h diff --git a/WebCore/bindings/js/JSCustomVoidCallback.cpp b/WebCore/bindings/js/JSCustomVoidCallback.cpp new file mode 100644 index 0000000..7964e59 --- /dev/null +++ b/WebCore/bindings/js/JSCustomVoidCallback.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSCustomVoidCallback.h" + +#include "CString.h" +#include "DOMWindow.h" +#include "Frame.h" +#include "kjs_binding.h" +#include "kjs_proxy.h" +#include "kjs_window.h" +#include "Page.h" + +namespace WebCore { + +using namespace KJS; + +JSCustomVoidCallback::JSCustomVoidCallback(JSObject* callback, Frame* frame) + : m_callback(callback) + , m_frame(frame) +{ +} + +void JSCustomVoidCallback::handleEvent() +{ + ASSERT(m_callback); + ASSERT(m_frame); + + if (!m_frame->scriptProxy()->isEnabled()) + return; + + JSGlobalObject* globalObject = m_frame->scriptProxy()->globalObject(); + ExecState* exec = globalObject->globalExec(); + + KJS::JSLock lock; + + JSValue* handleEventFuncValue = m_callback->get(exec, "handleEvent"); + JSObject* handleEventFunc = 0; + if (handleEventFuncValue->isObject()) { + handleEventFunc = static_cast<JSObject*>(handleEventFuncValue); + if (!handleEventFunc->implementsCall()) + handleEventFunc = 0; + } + + if (!handleEventFunc && !m_callback->implementsCall()) { + // FIXME: Should an exception be thrown here? + return; + } + + RefPtr<JSCustomVoidCallback> protect(this); + + List args; + + globalObject->startTimeoutCheck(); + if (handleEventFunc) + handleEventFunc->call(exec, m_callback, args); + else + m_callback->call(exec, m_callback, args); + globalObject->stopTimeoutCheck(); + + if (exec->hadException()) { + JSObject* exception = exec->exception()->toObject(exec); + String message = exception->get(exec, exec->propertyNames().message)->toString(exec); + int lineNumber = exception->get(exec, "line")->toInt32(exec); + String sourceURL = exception->get(exec, "sourceURL")->toString(exec); + if (Interpreter::shouldPrintExceptions()) + printf("VoidCallback: %s\n", message.utf8().data()); + if (Page* page = m_frame->page()) + page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, message, lineNumber, sourceURL); + exec->clearException(); + } + + Document::updateDocumentsRendering(); +} + +VoidCallback* toVoidCallback(ExecState* exec, JSValue* value, bool& ok) +{ + ok = false; + + JSObject* object = value->getObject(); + if (!object) + return 0; + + Frame* frame = Window::retrieveActive(exec)->impl()->frame(); + if (!frame) + return 0; + + ok = true; + return new JSCustomVoidCallback(object, frame); +} + +} diff --git a/WebCore/bindings/js/JSCustomVoidCallback.h b/WebCore/bindings/js/JSCustomVoidCallback.h new file mode 100644 index 0000000..1f97f39 --- /dev/null +++ b/WebCore/bindings/js/JSCustomVoidCallback.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSCustomVoidCallback_h +#define JSCustomVoidCallback_h + +#include "VoidCallback.h" + +#include <kjs/object.h> +#include <kjs/protect.h> +#include <wtf/Forward.h> + +namespace KJS { + class JSObject; +} + +namespace WebCore { + + class Frame; + class SQLError; + + class JSCustomVoidCallback : public VoidCallback { + public: + JSCustomVoidCallback(KJS::JSObject* callback, Frame*); + + virtual void handleEvent(); + private: + KJS::ProtectedPtr<KJS::JSObject> m_callback; + RefPtr<Frame> m_frame; + }; + + VoidCallback* toVoidCallback(KJS::ExecState*, KJS::JSValue*, bool& ok); +} + +#endif // JSCustomVoidCallback_h diff --git a/WebCore/bindings/js/JSCustomXPathNSResolver.cpp b/WebCore/bindings/js/JSCustomXPathNSResolver.cpp new file mode 100644 index 0000000..a8c4788 --- /dev/null +++ b/WebCore/bindings/js/JSCustomXPathNSResolver.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2007 Alexey Proskuryakov (ap@nypop.com) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSCustomXPathNSResolver.h" + +#if ENABLE(XPATH) + +#include "CString.h" +#include "DOMWindow.h" +#include "Document.h" +#include "ExceptionCode.h" +#include "Frame.h" +#include "Page.h" + +#include "kjs_binding.h" +#include "kjs_proxy.h" +#include "kjs_window.h" + +namespace WebCore { + +using namespace KJS; + +PassRefPtr<JSCustomXPathNSResolver> JSCustomXPathNSResolver::create(KJS::ExecState* exec, KJS::JSValue* value) +{ + if (value->isUndefinedOrNull()) + return 0; + + JSObject* resolverObject = value->getObject(); + if (!resolverObject) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return 0; + } + + return new JSCustomXPathNSResolver(resolverObject, KJS::Window::retrieveActive(exec)->impl()->frame()); +} + +JSCustomXPathNSResolver::JSCustomXPathNSResolver(JSObject* customResolver, Frame* frame) + : m_customResolver(customResolver) + , m_frame(frame) +{ +} + +JSCustomXPathNSResolver::~JSCustomXPathNSResolver() +{ +} + +String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix) +{ + ASSERT(m_customResolver); + + if (!m_frame) + return String(); + if (!m_frame->scriptProxy()->isEnabled()) + return String(); + + JSLock lock; + + JSGlobalObject* globalObject = m_frame->scriptProxy()->globalObject(); + ExecState* exec = globalObject->globalExec(); + + JSValue* lookupNamespaceURIFuncValue = m_customResolver->get(exec, "lookupNamespaceURI"); + JSObject* lookupNamespaceURIFunc = 0; + if (lookupNamespaceURIFuncValue->isObject()) { + lookupNamespaceURIFunc = static_cast<JSObject*>(lookupNamespaceURIFuncValue); + if (!lookupNamespaceURIFunc->implementsCall()) + lookupNamespaceURIFunc = 0; + } + + if (!lookupNamespaceURIFunc && !m_customResolver->implementsCall()) { + // FIXME: pass actual line number and source URL. + if (Page* page = m_frame->page()) + page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, "XPathNSResolver does not have a lookupNamespaceURI method.", 0, String()); + return String(); + } + + RefPtr<JSCustomXPathNSResolver> selfProtector(this); + + List args; + args.append(jsString(prefix)); + + String result; + JSValue* retval; + globalObject->startTimeoutCheck(); + if (lookupNamespaceURIFunc) + retval = lookupNamespaceURIFunc->call(exec, m_customResolver, args); + else + retval = m_customResolver->call(exec, m_customResolver, args); + globalObject->stopTimeoutCheck(); + + if (exec->hadException()) { + JSObject* exception = exec->exception()->toObject(exec); + String message = exception->get(exec, exec->propertyNames().message)->toString(exec); + int lineNumber = exception->get(exec, "line")->toInt32(exec); + String sourceURL = exception->get(exec, "sourceURL")->toString(exec); + if (Interpreter::shouldPrintExceptions()) + printf("XPathNSResolver: %s\n", message.utf8().data()); + if (Page* page = m_frame->page()) + page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, message, lineNumber, sourceURL); + exec->clearException(); + } else { + if (!retval->isUndefinedOrNull()) + result = retval->toString(exec); + } + + Document::updateDocumentsRendering(); + + return result; +} + +} // namespace WebCore + +#endif // ENABLE(XPATH) diff --git a/WebCore/bindings/js/JSCustomXPathNSResolver.h b/WebCore/bindings/js/JSCustomXPathNSResolver.h new file mode 100644 index 0000000..ddd407a --- /dev/null +++ b/WebCore/bindings/js/JSCustomXPathNSResolver.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2007 Alexey Proskuryakov (ap@nypop.com) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSCustomXPathNSResolver_h +#define JSCustomXPathNSResolver_h + +#if ENABLE(XPATH) + +#include "XPathNSResolver.h" +#include <wtf/Forward.h> +#include <wtf/RefPtr.h> + +namespace KJS { + class ExecState; + class JSObject; + class JSValue; +} + +namespace WebCore { + + class Frame; + + class JSCustomXPathNSResolver : public XPathNSResolver { + public: + static PassRefPtr<JSCustomXPathNSResolver> create(KJS::ExecState*, KJS::JSValue*); + + virtual ~JSCustomXPathNSResolver(); + + virtual String lookupNamespaceURI(const String& prefix); + + private: + JSCustomXPathNSResolver(KJS::JSObject*, Frame*); + + KJS::JSObject* m_customResolver; // JSCustomXPathNSResolvers are always temporary, thus no need to GC protect the object. + RefPtr<Frame> m_frame; + }; + +} // namespace WebCore + +#endif // ENABLE(XPATH) + +#endif // JSCustomXPathNSResolver_h diff --git a/WebCore/bindings/js/JSDOMWindowCustom.cpp b/WebCore/bindings/js/JSDOMWindowCustom.cpp new file mode 100644 index 0000000..af2353c --- /dev/null +++ b/WebCore/bindings/js/JSDOMWindowCustom.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "JSDOMWindow.h" + +#include "AtomicString.h" +#include "DOMWindow.h" +#include "Document.h" +#include "ExceptionCode.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "FrameTree.h" +#include "kjs_window.h" +#include <kjs/object.h> + +using namespace KJS; + +namespace WebCore { + +bool JSDOMWindow::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + // 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 closed window. + if (!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 = Lookup::findEntry(info.propHashTable, propertyName); + if (entry && !(entry->attr & Function) && entry->value.intValue == ClosedAttrNum) { + slot.setStaticEntry(this, entry, staticValueGetter<JSDOMWindow>); + return true; + } + entry = Lookup::findEntry(JSDOMWindowPrototype::info.propHashTable, propertyName); + if (entry && (entry->attr & Function) && entry->value.functionValue == jsDOMWindowPrototypeFunctionClose) { + slot.setStaticEntry(this, entry, nonCachingStaticFunctionGetter); + return true; + } + + // FIXME: We should have a message here that explains why the property access/function call was + // not allowed. + slot.setUndefined(this); + 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. + bool allowsAccess = allowsAccessFromNoErrorMessage(exec); + + // Look for overrides before looking at any of our own properties. + if (JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot)) { + // But ignore overrides completely if this is cross-domain access. + if (allowsAccess) + return true; + } + + // We need this code here because otherwise KJS::Window will stop the search before we even get to the + // prototype due to the blanket same origin (allowsAccessFrom) 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 = Lookup::findEntry(JSDOMWindowPrototype::info.propHashTable, propertyName); + if (entry) { + if ((entry->attr & Function) + && (entry->value.functionValue == jsDOMWindowPrototypeFunctionBlur + || entry->value.functionValue == jsDOMWindowPrototypeFunctionClose + || entry->value.functionValue == jsDOMWindowPrototypeFunctionFocus +#if ENABLE(CROSS_DOCUMENT_MESSAGING) + || entry->value.functionValue == jsDOMWindowPrototypeFunctionPostMessage +#endif + )) { + if (!allowsAccess) { + slot.setStaticEntry(this, entry, nonCachingStaticFunctionGetter); + return true; + } + } + } else { + // Allow access to toString() cross-domain, but always Object.prototype.toString. + if (propertyName == exec->propertyNames().toString) { + if (!allowsAccess) { + slot.setCustom(this, objectToStringFunctionGetter); + return true; + } + } + } + + return false; +} + +bool JSDOMWindow::customPut(ExecState* exec, const Identifier& propertyName, JSValue* value) +{ + if (!impl()->frame()) + return true; + + // We have a local override (e.g. "var location"), save time and jump directly to JSGlobalObject. + PropertySlot slot; + if (JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot)) { + if (allowsAccessFrom(exec)) + JSGlobalObject::put(exec, propertyName, value); + return true; + } + + return false; +} + +bool JSDOMWindow::deleteProperty(ExecState* exec, const Identifier& propertyName) +{ + // Only allow deleting properties by frames in the same origin. + if (!allowsAccessFrom(exec)) + return false; + return Base::deleteProperty(exec, propertyName); +} + +bool JSDOMWindow::customGetPropertyNames(ExecState* exec, PropertyNameArray&) +{ + // Only allow the window to enumerated by frames in the same origin. + if (!allowsAccessFrom(exec)) + return true; + return false; +} + +#if ENABLE(CROSS_DOCUMENT_MESSAGING) +JSValue* JSDOMWindow::postMessage(ExecState* exec, const List& args) +{ + DOMWindow* window = impl(); + + DOMWindow* source = static_cast<JSDOMWindow*>(exec->dynamicGlobalObject())->impl(); + String domain = source->frame()->loader()->url().host(); + String uri = source->frame()->loader()->url().string(); + String message = args[0]->toString(exec); + + if (exec->hadException()) + return jsUndefined(); + + window->postMessage(message, domain, uri, source); + + return jsUndefined(); +} +#endif + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSDatabaseCustom.cpp b/WebCore/bindings/js/JSDatabaseCustom.cpp new file mode 100644 index 0000000..c4e9265 --- /dev/null +++ b/WebCore/bindings/js/JSDatabaseCustom.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSDatabase.h" + +#include "Database.h" +#include "Document.h" +#include "DOMWindow.h" +#include "ExceptionCode.h" +#include "kjs_window.h" +#include "JSCustomSQLTransactionCallback.h" +#include "JSCustomSQLTransactionErrorCallback.h" +#include "JSCustomVoidCallback.h" +#include "PlatformString.h" +#include "SQLValue.h" +#include <kjs/array_instance.h> + +namespace WebCore { + +using namespace KJS; + +JSValue* JSDatabase::changeVersion(ExecState* exec, const List& args) +{ + String oldVersion = args[0]->toString(exec); + String newVersion = args[1]->toString(exec); + + Frame* frame = Window::retrieveActive(exec)->impl()->frame(); + if (!frame) + return jsUndefined(); + + JSObject *object; + if (!(object = args[2]->getObject())) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + RefPtr<SQLTransactionCallback> callback(new JSCustomSQLTransactionCallback(object, frame)); + + RefPtr<SQLTransactionErrorCallback> errorCallback; + if (!args[3]->isNull()) { + if (!(object = args[3]->getObject())) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + errorCallback = new JSCustomSQLTransactionErrorCallback(object, frame); + } + + RefPtr<VoidCallback> successCallback; + if (!args[4]->isNull()) { + bool ok; + successCallback = toVoidCallback(exec, args[4], ok); + if (!ok) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + } + + m_impl->changeVersion(oldVersion, newVersion, callback.release(), errorCallback.release(), successCallback.release()); + + return jsUndefined(); +} + +JSValue* JSDatabase::transaction(ExecState* exec, const List& args) +{ + JSObject* object; + + if (!(object = args[0]->getObject())) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + Frame* frame = Window::retrieveActive(exec)->impl()->frame(); + if (!frame) + return jsUndefined(); + + RefPtr<SQLTransactionCallback> callback(new JSCustomSQLTransactionCallback(object, frame)); + RefPtr<SQLTransactionErrorCallback> errorCallback; + + if (args.size() > 1 && !args[1]->isNull()) { + if (!(object = args[1]->getObject())) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + errorCallback = new JSCustomSQLTransactionErrorCallback(object, frame); + } + + RefPtr<VoidCallback> successCallback; + if (args.size() > 2 && !args[2]->isNull()) { + bool ok; + successCallback = toVoidCallback(exec, args[2], ok); + if (!ok) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + } + + m_impl->transaction(callback.release(), errorCallback.release(), successCallback.release()); + + return jsUndefined(); +} + +} diff --git a/WebCore/bindings/js/JSDocumentCustom.cpp b/WebCore/bindings/js/JSDocumentCustom.cpp new file mode 100644 index 0000000..a957405 --- /dev/null +++ b/WebCore/bindings/js/JSDocumentCustom.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "JSDocument.h" + +#include "DOMWindow.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "HTMLDocument.h" +#include "JSDOMWindow.h" +#include "JSHTMLDocument.h" +#include "JSLocation.h" +#include "kjs_proxy.h" + +#if ENABLE(SVG) +#include "JSSVGDocument.h" +#include "SVGDocument.h" +#endif + +using namespace KJS; + +namespace WebCore { + +void JSDocument::mark() +{ + JSEventTargetNode::mark(); + ScriptInterpreter::markDOMNodesForDocument(static_cast<Document*>(impl())); +} + +JSValue* JSDocument::location(ExecState* exec) const +{ + Frame* frame = static_cast<Document*>(impl())->frame(); + if (!frame) + return jsNull(); + + Window* win = Window::retrieveWindow(frame); + ASSERT(win); + return win->location(); +} + +void JSDocument::setLocation(ExecState* exec, JSValue* value) +{ + Frame* frame = static_cast<Document*>(impl())->frame(); + if (!frame) + return; + + String str = value->toString(exec); + + // IE and Mozilla both resolve the URL relative to the source frame, + // not the target frame. + Frame* activeFrame = static_cast<JSDOMWindow*>(exec->dynamicGlobalObject())->impl()->frame(); + if (activeFrame) + str = activeFrame->document()->completeURL(str).string(); + + bool userGesture = activeFrame->scriptProxy()->processingUserGesture(); + frame->loader()->scheduleLocationChange(str, activeFrame->loader()->outgoingReferrer(), false, userGesture); +} + +JSValue* toJS(ExecState* exec, Document* doc) +{ + if (!doc) + return jsNull(); + + JSDocument* ret = static_cast<JSDocument*>(ScriptInterpreter::getDOMObject(doc)); + if (ret) + return ret; + + if (doc->isHTMLDocument()) + ret = new JSHTMLDocument(JSHTMLDocumentPrototype::self(exec), static_cast<HTMLDocument*>(doc)); +#if ENABLE(SVG) + else if (doc->isSVGDocument()) + ret = new JSSVGDocument(JSSVGDocumentPrototype::self(exec), static_cast<SVGDocument*>(doc)); +#endif + else + ret = new JSDocument(JSDocumentPrototype::self(exec), doc); + + // Make sure the document is kept around by the window object, and works right with the + // back/forward cache. + if (doc->frame()) + Window::retrieveWindow(doc->frame())->putDirect("document", ret, DontDelete|ReadOnly); + else { + size_t nodeCount = 0; + for (Node* n = doc; n; n = n->traverseNextNode()) + nodeCount++; + + Collector::reportExtraMemoryCost(nodeCount * sizeof(Node)); + } + + ScriptInterpreter::putDOMObject(doc, ret); + + return ret; +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSElementCustom.cpp b/WebCore/bindings/js/JSElementCustom.cpp new file mode 100644 index 0000000..814ef06 --- /dev/null +++ b/WebCore/bindings/js/JSElementCustom.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "config.h" +#include "JSElement.h" + +#include "CSSHelper.h" +#include "ExceptionCode.h" +#include "HTMLFrameElementBase.h" +#include "HTMLNames.h" + +using namespace KJS; + +namespace WebCore { + +using namespace HTMLNames; + +static inline bool allowSettingSrcToJavascriptURL(ExecState* exec, Element* element, const String& name, const String& value) +{ + if ((element->hasTagName(iframeTag) || element->hasTagName(frameTag)) && equalIgnoringCase(name, "src") && protocolIs(parseURL(value), "javascript")) { + HTMLFrameElementBase* frame = static_cast<HTMLFrameElementBase*>(element); + if (!checkNodeSecurity(exec, frame->contentDocument())) + return false; + } + return true; +} + +JSValue* JSElement::setAttribute(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + String name = args[0]->toString(exec); + String value = args[1]->toString(exec); + + Element* imp = impl(); + if (!allowSettingSrcToJavascriptURL(exec, imp, name, value)) + return jsUndefined(); + + imp->setAttribute(name, value, ec); + setDOMException(exec, ec); + return jsUndefined(); +} + +JSValue* JSElement::setAttributeNode(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + bool newAttrOk; + Attr* newAttr = toAttr(args[0], newAttrOk); + if (!newAttrOk) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + Element* imp = impl(); + if (!allowSettingSrcToJavascriptURL(exec, imp, newAttr->name(), newAttr->value())) + return jsUndefined(); + + JSValue* result = toJS(exec, WTF::getPtr(imp->setAttributeNode(newAttr, ec))); + setDOMException(exec, ec); + return result; +} + +JSValue* JSElement::setAttributeNS(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + String namespaceURI = valueToStringWithNullCheck(exec, args[0]); + String qualifiedName = args[1]->toString(exec); + String value = args[2]->toString(exec); + + Element* imp = impl(); + if (!allowSettingSrcToJavascriptURL(exec, imp, qualifiedName, value)) + return jsUndefined(); + + imp->setAttributeNS(namespaceURI, qualifiedName, value, ec); + setDOMException(exec, ec); + return jsUndefined(); +} + +JSValue* JSElement::setAttributeNodeNS(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + bool newAttrOk; + Attr* newAttr = toAttr(args[0], newAttrOk); + if (!newAttrOk) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + Element* imp = impl(); + if (!allowSettingSrcToJavascriptURL(exec, imp, newAttr->name(), newAttr->value())) + return jsUndefined(); + + JSValue* result = toJS(exec, WTF::getPtr(imp->setAttributeNodeNS(newAttr, ec))); + setDOMException(exec, ec); + return result; +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSEventCustom.cpp b/WebCore/bindings/js/JSEventCustom.cpp new file mode 100644 index 0000000..e1e044c --- /dev/null +++ b/WebCore/bindings/js/JSEventCustom.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSEvent.h" + +#include "Clipboard.h" +#include "Event.h" +#include "JSKeyboardEvent.h" +#include "JSMouseEvent.h" +#include "JSMutationEvent.h" +#include "JSOverflowEvent.h" +#include "JSProgressEvent.h" +#include "JSTextEvent.h" +#include "JSUIEvent.h" +#include "JSWheelEvent.h" +#include "KeyboardEvent.h" +#include "MouseEvent.h" +#include "MutationEvent.h" +#include "OverflowEvent.h" +#include "ProgressEvent.h" +#include "TextEvent.h" +#include "UIEvent.h" +#include "WheelEvent.h" +#include "kjs_events.h" + +#if ENABLE(CROSS_DOCUMENT_MESSAGING) +#include "JSMessageEvent.h" +#include "MessageEvent.h" +#endif + +#if ENABLE(SVG) +#include "JSSVGZoomEvent.h" +#include "SVGZoomEvent.h" +#endif + +using namespace KJS; + +namespace WebCore { + +JSValue* JSEvent::clipboardData(ExecState* exec) const +{ + return impl()->isClipboardEvent() ? toJS(exec, impl()->clipboardData()) : jsUndefined(); +} + +JSValue* toJS(ExecState* exec, Event* event) +{ + JSLock lock; + + if (!event) + return jsNull(); + + DOMObject* ret = ScriptInterpreter::getDOMObject(event); + if (ret) + return ret; + + if (event->isUIEvent()) { + if (event->isKeyboardEvent()) + ret = new JSKeyboardEvent(JSKeyboardEventPrototype::self(exec), static_cast<KeyboardEvent*>(event)); + else if (event->isTextEvent()) + ret = new JSTextEvent(JSTextEventPrototype::self(exec), static_cast<TextEvent*>(event)); + else if (event->isMouseEvent()) + ret = new JSMouseEvent(JSMouseEventPrototype::self(exec), static_cast<MouseEvent*>(event)); + else if (event->isWheelEvent()) + ret = new JSWheelEvent(JSWheelEventPrototype::self(exec), static_cast<WheelEvent*>(event)); +#if ENABLE(SVG) + else if (event->isSVGZoomEvent()) + ret = new JSSVGZoomEvent(JSSVGZoomEventPrototype::self(exec), static_cast<SVGZoomEvent*>(event), 0); +#endif + else + ret = new JSUIEvent(JSUIEventPrototype::self(exec), static_cast<UIEvent*>(event)); + } else if (event->isMutationEvent()) + ret = new JSMutationEvent(JSMutationEventPrototype::self(exec), static_cast<MutationEvent*>(event)); + else if (event->isOverflowEvent()) + ret = new JSOverflowEvent(JSOverflowEventPrototype::self(exec), static_cast<OverflowEvent*>(event)); +#if ENABLE(CROSS_DOCUMENT_MESSAGING) + else if (event->isMessageEvent()) + ret = new JSMessageEvent(JSMessageEventPrototype::self(exec), static_cast<MessageEvent*>(event)); +#endif + else if (event->isProgressEvent()) + ret = new JSProgressEvent(JSProgressEventPrototype::self(exec), static_cast<ProgressEvent*>(event)); + else + ret = new JSEvent(JSEventPrototype::self(exec), event); + + ScriptInterpreter::putDOMObject(event, ret); + return ret; +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSEventTargetBase.cpp b/WebCore/bindings/js/JSEventTargetBase.cpp new file mode 100644 index 0000000..d15171c --- /dev/null +++ b/WebCore/bindings/js/JSEventTargetBase.cpp @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSEventTargetBase.h" + +#include "JSEventTargetNode.h" + +#include "JSEventTargetBase.lut.h" + +using namespace KJS; + +namespace WebCore { + +/* Source for JSEventTargetPropertiesTable +@begin JSEventTargetPropertiesTable 50 +onabort WebCore::JSEventTargetProperties::OnAbort DontDelete +onblur WebCore::JSEventTargetProperties::OnBlur DontDelete +onchange WebCore::JSEventTargetProperties::OnChange DontDelete +onclick WebCore::JSEventTargetProperties::OnClick DontDelete +oncontextmenu WebCore::JSEventTargetProperties::OnContextMenu DontDelete +ondblclick WebCore::JSEventTargetProperties::OnDblClick DontDelete +onbeforecut WebCore::JSEventTargetProperties::OnBeforeCut DontDelete +oncut WebCore::JSEventTargetProperties::OnCut DontDelete +onbeforecopy WebCore::JSEventTargetProperties::OnBeforeCopy DontDelete +oncopy WebCore::JSEventTargetProperties::OnCopy DontDelete +onbeforepaste WebCore::JSEventTargetProperties::OnBeforePaste DontDelete +onpaste WebCore::JSEventTargetProperties::OnPaste DontDelete +ondrag WebCore::JSEventTargetProperties::OnDrag DontDelete +ondragend WebCore::JSEventTargetProperties::OnDragEnd DontDelete +ondragenter WebCore::JSEventTargetProperties::OnDragEnter DontDelete +ondragleave WebCore::JSEventTargetProperties::OnDragLeave DontDelete +ondragover WebCore::JSEventTargetProperties::OnDragOver DontDelete +ondragstart WebCore::JSEventTargetProperties::OnDragStart DontDelete +ondrop WebCore::JSEventTargetProperties::OnDrop DontDelete +onerror WebCore::JSEventTargetProperties::OnError DontDelete +onfocus WebCore::JSEventTargetProperties::OnFocus DontDelete +oninput WebCore::JSEventTargetProperties::OnInput DontDelete +onkeydown WebCore::JSEventTargetProperties::OnKeyDown DontDelete +onkeypress WebCore::JSEventTargetProperties::OnKeyPress DontDelete +onkeyup WebCore::JSEventTargetProperties::OnKeyUp DontDelete +onload WebCore::JSEventTargetProperties::OnLoad DontDelete +onmousedown WebCore::JSEventTargetProperties::OnMouseDown DontDelete +onmousemove WebCore::JSEventTargetProperties::OnMouseMove DontDelete +onmouseout WebCore::JSEventTargetProperties::OnMouseOut DontDelete +onmouseover WebCore::JSEventTargetProperties::OnMouseOver DontDelete +onmouseup WebCore::JSEventTargetProperties::OnMouseUp DontDelete +onmousewheel WebCore::JSEventTargetProperties::OnMouseWheel DontDelete +onreset WebCore::JSEventTargetProperties::OnReset DontDelete +onresize WebCore::JSEventTargetProperties::OnResize DontDelete +onscroll WebCore::JSEventTargetProperties::OnScroll DontDelete +onsearch WebCore::JSEventTargetProperties::OnSearch DontDelete +onselect WebCore::JSEventTargetProperties::OnSelect DontDelete +onselectstart WebCore::JSEventTargetProperties::OnSelectStart DontDelete +onsubmit WebCore::JSEventTargetProperties::OnSubmit DontDelete +onunload WebCore::JSEventTargetProperties::OnUnload DontDelete +@end +*/ + +/* +@begin JSEventTargetPrototypeTable 5 +addEventListener WebCore::jsEventTargetAddEventListener DontDelete|Function 3 +removeEventListener WebCore::jsEventTargetRemoveEventListener DontDelete|Function 3 +dispatchEvent WebCore::jsEventTargetDispatchEvent DontDelete|Function 1 +@end +*/ + +JSValue* jsEventTargetAddEventListener(ExecState* exec, JSObject* thisObj, const List& args) +{ + DOMExceptionTranslator exception(exec); + + Node* eventNode = 0; + EventTarget* eventTarget = 0; + if (!retrieveEventTargetAndCorrespondingNode(exec, thisObj, eventNode, eventTarget)) + return throwError(exec, TypeError); + + Frame* frame = eventNode->document()->frame(); + if (!frame) + return jsUndefined(); + + if (JSEventListener* listener = Window::retrieveWindow(frame)->findOrCreateJSEventListener(args[1])) + eventTarget->addEventListener(args[0]->toString(exec), listener, args[2]->toBoolean(exec)); + + return jsUndefined(); +} + +JSValue* jsEventTargetRemoveEventListener(ExecState* exec, JSObject* thisObj, const List& args) +{ + DOMExceptionTranslator exception(exec); + + Node* eventNode = 0; + EventTarget* eventTarget = 0; + if (!retrieveEventTargetAndCorrespondingNode(exec, thisObj, eventNode, eventTarget)) + return throwError(exec, TypeError); + + Frame* frame = eventNode->document()->frame(); + if (!frame) + return jsUndefined(); + + if (JSEventListener* listener = Window::retrieveWindow(frame)->findJSEventListener(args[1])) + eventTarget->removeEventListener(args[0]->toString(exec), listener, args[2]->toBoolean(exec)); + + return jsUndefined(); +} + +JSValue* jsEventTargetDispatchEvent(ExecState* exec, JSObject* thisObj, const List& args) +{ + Node* eventNode = 0; + EventTarget* eventTarget = 0; + if (!retrieveEventTargetAndCorrespondingNode(exec, thisObj, eventNode, eventTarget)) + return throwError(exec, TypeError); + + DOMExceptionTranslator exception(exec); + return jsBoolean(eventTarget->dispatchEvent(toEvent(args[0]), exception)); +} + +bool retrieveEventTargetAndCorrespondingNode(KJS::ExecState*, KJS::JSObject* thisObj, Node*& eventNode, EventTarget*& eventTarget) +{ + if (!thisObj->inherits(&JSNode::info)) + return false; + + JSEventTargetNode* jsNode = static_cast<JSEventTargetNode*>(thisObj); + ASSERT(jsNode); + + EventTargetNode* node = static_cast<EventTargetNode*>(jsNode->impl()); + ASSERT(node); + + eventNode = node; + eventTarget = node; + return true; +} + +AtomicString eventNameForPropertyToken(int token) +{ + switch (token) { + case JSEventTargetProperties::OnAbort: + return abortEvent; + case JSEventTargetProperties::OnBlur: + return blurEvent; + case JSEventTargetProperties::OnChange: + return changeEvent; + case JSEventTargetProperties::OnClick: + return clickEvent; + case JSEventTargetProperties::OnContextMenu: + return contextmenuEvent; + case JSEventTargetProperties::OnDblClick: + return dblclickEvent; + case JSEventTargetProperties::OnError: + return errorEvent; + case JSEventTargetProperties::OnFocus: + return focusEvent; + case JSEventTargetProperties::OnInput: + return inputEvent; + case JSEventTargetProperties::OnKeyDown: + return keydownEvent; + case JSEventTargetProperties::OnKeyPress: + return keypressEvent; + case JSEventTargetProperties::OnKeyUp: + return keyupEvent; + case JSEventTargetProperties::OnLoad: + return loadEvent; + case JSEventTargetProperties::OnMouseDown: + return mousedownEvent; + case JSEventTargetProperties::OnMouseMove: + return mousemoveEvent; + case JSEventTargetProperties::OnMouseOut: + return mouseoutEvent; + case JSEventTargetProperties::OnMouseOver: + return mouseoverEvent; + case JSEventTargetProperties::OnMouseUp: + return mouseupEvent; + case JSEventTargetProperties::OnMouseWheel: + return mousewheelEvent; + case JSEventTargetProperties::OnBeforeCut: + return beforecutEvent; + case JSEventTargetProperties::OnCut: + return cutEvent; + case JSEventTargetProperties::OnBeforeCopy: + return beforecopyEvent; + case JSEventTargetProperties::OnCopy: + return copyEvent; + case JSEventTargetProperties::OnBeforePaste: + return beforepasteEvent; + case JSEventTargetProperties::OnPaste: + return pasteEvent; + case JSEventTargetProperties::OnDragEnter: + return dragenterEvent; + case JSEventTargetProperties::OnDragOver: + return dragoverEvent; + case JSEventTargetProperties::OnDragLeave: + return dragleaveEvent; + case JSEventTargetProperties::OnDrop: + return dropEvent; + case JSEventTargetProperties::OnDragStart: + return dragstartEvent; + case JSEventTargetProperties::OnDrag: + return dragEvent; + case JSEventTargetProperties::OnDragEnd: + return dragendEvent; + case JSEventTargetProperties::OnReset: + return resetEvent; + case JSEventTargetProperties::OnResize: + return resizeEvent; + case JSEventTargetProperties::OnScroll: + return scrollEvent; + case JSEventTargetProperties::OnSearch: + return searchEvent; + case JSEventTargetProperties::OnSelect: + return selectEvent; + case JSEventTargetProperties::OnSelectStart: + return selectstartEvent; + case JSEventTargetProperties::OnSubmit: + return submitEvent; + case JSEventTargetProperties::OnUnload: + return unloadEvent; + } + + return AtomicString(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSEventTargetBase.h b/WebCore/bindings/js/JSEventTargetBase.h new file mode 100644 index 0000000..218ad18 --- /dev/null +++ b/WebCore/bindings/js/JSEventTargetBase.h @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSEventTargetBase_h +#define JSEventTargetBase_h + +#include "Document.h" +#include "Event.h" +#include "EventNames.h" +#include "JSEvent.h" +#include "kjs_events.h" +#include "kjs_window.h" + +namespace KJS { + + extern const struct HashTable JSEventTargetPropertiesTable; + extern const struct HashTable JSEventTargetPrototypeTable; + +} + +namespace WebCore { + + using namespace EventNames; + + class AtomicString; + class EventTarget; + + // Event target properties (shared across all JSEventTarget* classes) + struct JSEventTargetProperties { + enum { + AddEventListener, RemoveEventListener, DispatchEvent, + OnAbort, OnBlur, OnChange, OnClick, OnContextMenu, OnDblClick, OnError, + OnDragEnter, OnDragOver, OnDragLeave, OnDrop, OnDragStart, OnDrag, OnDragEnd, + OnBeforeCut, OnCut, OnBeforeCopy, OnCopy, OnBeforePaste, OnPaste, OnSelectStart, + OnFocus, OnInput, OnKeyDown, OnKeyPress, OnKeyUp, OnLoad, OnMouseDown, + OnMouseMove, OnMouseOut, OnMouseOver, OnMouseUp, OnMouseWheel, OnReset, + OnResize, OnScroll, OnSearch, OnSelect, OnSubmit, OnUnload + }; + }; + + // Helper function for the partial specializated template functions below + bool retrieveEventTargetAndCorrespondingNode(KJS::ExecState*, KJS::JSObject* thisObj, Node*&, EventTarget*&); + + // Functions + KJS::JSValue* jsEventTargetAddEventListener(KJS::ExecState*, KJS::JSObject*, const KJS::List&); + KJS::JSValue* jsEventTargetRemoveEventListener(KJS::ExecState*, KJS::JSObject*, const KJS::List&); + KJS::JSValue* jsEventTargetDispatchEvent(KJS::ExecState*, KJS::JSObject*, const KJS::List&); + + // Helper function for getValueProperty/putValueProperty + AtomicString eventNameForPropertyToken(int token); + + template<class JSEventTarget> + class JSEventTargetBase { + public: + JSEventTargetBase() { } + + KJS::JSValue* getValueProperty(const JSEventTarget* owner, KJS::ExecState* exec, int token) const + { + AtomicString eventName = eventNameForPropertyToken(token); + if (!eventName.isEmpty()) + return owner->getListener(eventName); + + return KJS::jsUndefined(); + } + + void putValueProperty(const JSEventTarget* owner, KJS::ExecState* exec, int token, KJS::JSValue* value) + { + AtomicString eventName = eventNameForPropertyToken(token); + if (!eventName.isEmpty()) + owner->setListener(exec, eventName, value); + } + + private: + friend class JSEventTargetNode; + friend class JSEventTargetSVGElementInstance; + + template<class JSParent> + bool getOwnPropertySlot(JSEventTarget* owner, KJS::ExecState* exec, const KJS::Identifier& propertyName, KJS::PropertySlot& slot) + { + return KJS::getStaticValueSlot<JSEventTarget, JSParent>(exec, &KJS::JSEventTargetPropertiesTable, owner, propertyName, slot); + } + + template<class JSParent> + void put(JSEventTarget* owner, KJS::ExecState* exec, const KJS::Identifier& propertyName, KJS::JSValue* value) + { + KJS::lookupPut<JSEventTarget, JSParent>(exec, propertyName, value, &KJS::JSEventTargetPropertiesTable, owner); + } + }; + + // This class is a modified version of the code the KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE + // and KJS_IMPLEMENT_PROTOTYPE macros produce - the idea is that classes like JSEventTargetNode + // and JSEventTargetSVGElementInstance can share a single prototype just differing in the + // naming "EventTargetNodePrototype" vs "EventTargetSVGElementInstancePrototype". Above mentioned + // macros force the existance of several prototype tables for each of the classes - avoid that. + template<class JSEventTargetPrototypeParent, class JSEventTargetPrototypeInformation> + class JSEventTargetPrototype : public KJS::JSObject { + public: + JSEventTargetPrototype(KJS::ExecState* exec) + : KJS::JSObject(JSEventTargetPrototypeParent::self(exec)) + { + } + + static KJS::JSObject* self(KJS::ExecState* exec) + { + static KJS::Identifier* prototypeName = new KJS::Identifier(JSEventTargetPrototypeInformation::prototypeClassName()); + + KJS::JSGlobalObject* globalObject = exec->lexicalGlobalObject(); + if (KJS::JSValue* objectValue = globalObject->getDirect(*prototypeName)) { + ASSERT(objectValue->isObject()); + return static_cast<KJS::JSObject*>(objectValue); + } + + KJS::JSObject* newObject = new JSEventTargetPrototype<JSEventTargetPrototypeParent, JSEventTargetPrototypeInformation>(exec); + globalObject->putDirect(*prototypeName, newObject, KJS::DontEnum); + return newObject; + } + + bool getOwnPropertySlot(KJS::ExecState* exec, const KJS::Identifier& propertyName, KJS::PropertySlot& slot) + { + return KJS::getStaticFunctionSlot<KJS::JSObject>(exec, &KJS::JSEventTargetPrototypeTable, this, propertyName, slot); + } + + virtual const KJS::ClassInfo* classInfo() const + { + static const KJS::ClassInfo s_classInfo = { JSEventTargetPrototypeInformation::prototypeClassName(), 0, &KJS::JSEventTargetPrototypeTable }; + return &s_classInfo; + } + }; + +} // namespace WebCore + +#endif // JSEventTargetBase_h diff --git a/WebCore/bindings/js/JSEventTargetNode.cpp b/WebCore/bindings/js/JSEventTargetNode.cpp new file mode 100644 index 0000000..92c0048 --- /dev/null +++ b/WebCore/bindings/js/JSEventTargetNode.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSEventTargetNode.h" + +namespace WebCore { + +using namespace KJS; + +JSEventTargetNode::JSEventTargetNode(JSObject* prototype, Node* node) + : JSNode(prototype, node) +{ +} + +bool JSEventTargetNode::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + return m_base.getOwnPropertySlot<JSNode>(this, exec, propertyName, slot); +} + +JSValue* JSEventTargetNode::getValueProperty(ExecState* exec, int token) const +{ + return m_base.getValueProperty(this, exec, token); +} + +void JSEventTargetNode::put(ExecState* exec, const Identifier& propertyName, JSValue* value) +{ + m_base.put<JSNode>(this, exec, propertyName, value); +} + +void JSEventTargetNode::putValueProperty(ExecState* exec, int token, JSValue* value) +{ + m_base.putValueProperty(this, exec, token, value); +} + +void JSEventTargetNode::setListener(ExecState* exec, const AtomicString& eventType, JSValue* func) const +{ + Frame* frame = impl()->document()->frame(); + if (frame) + EventTargetNodeCast(impl())->setHTMLEventListener(eventType, KJS::Window::retrieveWindow(frame)->findOrCreateJSEventListener(func, true)); +} + +JSValue* JSEventTargetNode::getListener(const AtomicString& eventType) const +{ + EventListener* listener = EventTargetNodeCast(impl())->getHTMLEventListener(eventType); + JSEventListener* jsListener = static_cast<JSEventListener*>(listener); + if (jsListener && jsListener->listenerObj()) + return jsListener->listenerObj(); + + return jsNull(); +} + +void JSEventTargetNode::pushEventHandlerScope(ExecState*, ScopeChain&) const +{ +} + +EventTargetNode* toEventTargetNode(JSValue* val) +{ + if (!val || !val->isObject(&JSEventTargetNode::info)) + return 0; + + return static_cast<EventTargetNode*>(static_cast<JSEventTargetNode*>(val)->impl()); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSEventTargetNode.h b/WebCore/bindings/js/JSEventTargetNode.h new file mode 100644 index 0000000..f83490a --- /dev/null +++ b/WebCore/bindings/js/JSEventTargetNode.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSEventTargetNode_h +#define JSEventTargetNode_h + +#include "JSNode.h" +#include "JSEventTargetBase.h" + +namespace WebCore { + + class EventTargetNode; + class Node; + + class JSEventTargetNode : public JSNode { + public: + JSEventTargetNode(KJS::JSObject* prototype, Node*); + + void setListener(KJS::ExecState*, const AtomicString& eventType, KJS::JSValue* func) const; + KJS::JSValue* getListener(const AtomicString& eventType) const; + virtual void pushEventHandlerScope(KJS::ExecState*, KJS::ScopeChain&) const; + + bool getOwnPropertySlot(KJS::ExecState*, const KJS::Identifier&, KJS::PropertySlot&); + KJS::JSValue* getValueProperty(KJS::ExecState*, int token) const; + virtual void put(KJS::ExecState*, const KJS::Identifier&, KJS::JSValue*); + void putValueProperty(KJS::ExecState*, int token, KJS::JSValue*); + + private: + JSEventTargetBase<JSEventTargetNode> m_base; + }; + + struct JSEventTargetPrototypeInformation { + static const char* prototypeClassName() + { + return "EventTargetNodePrototype"; + } + + static const char* prototypeIdentifier() + { + return "[[EventTargetNode.prototype]]"; + } + }; + + typedef JSEventTargetPrototype<JSNodePrototype, JSEventTargetPrototypeInformation> JSEventTargetNodePrototype; + EventTargetNode* toEventTargetNode(KJS::JSValue*); + +} // namespace WebCore + +#endif // JSEventTargetNode_h diff --git a/WebCore/bindings/js/JSHTMLAllCollection.h b/WebCore/bindings/js/JSHTMLAllCollection.h new file mode 100644 index 0000000..4661e12 --- /dev/null +++ b/WebCore/bindings/js/JSHTMLAllCollection.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSHTMLAllCollection_h +#define JSHTMLAllCollection_h + +#include "JSHTMLCollection.h" + +namespace WebCore { + + class HTMLCollection; + + class JSHTMLAllCollection : public JSHTMLCollection { + public: + JSHTMLAllCollection(KJS::JSObject* prototype, HTMLCollection* collection) + : JSHTMLCollection(prototype, collection) + { + } + + virtual bool toBoolean(KJS::ExecState*) const { return false; } + virtual bool masqueradeAsUndefined() const { return true; } + }; + +} // namespace WebCore + +#endif // JSHTMLAllCollection_h diff --git a/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp b/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp new file mode 100644 index 0000000..d34b8b5 --- /dev/null +++ b/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSHTMLAppletElement.h" + +#include "HTMLAppletElement.h" +#include "kjs_dom.h" +#include "kjs_html.h" + +namespace WebCore { + +using namespace KJS; + +bool JSHTMLAppletElement::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + return runtimeObjectCustomGetOwnPropertySlot(exec, propertyName, slot, this, static_cast<HTMLElement*>(impl())); +} + +bool JSHTMLAppletElement::customPut(ExecState* exec, const Identifier& propertyName, JSValue* value) +{ + return runtimeObjectCustomPut(exec, propertyName, value, static_cast<HTMLElement*>(impl())); +} + +bool JSHTMLAppletElement::implementsCall() const +{ + return runtimeObjectImplementsCall(static_cast<HTMLElement*>(impl())); +} + +JSValue* JSHTMLAppletElement::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args) +{ + return runtimeObjectCallAsFunction(exec, thisObj, args, static_cast<HTMLElement*>(impl())); +} + +bool JSHTMLAppletElement::canGetItemsForName(ExecState*, HTMLAppletElement*, const Identifier& propertyName) +{ + return propertyName == "__apple_runtime_object"; +} + +JSValue* JSHTMLAppletElement::nameGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot) +{ + return runtimeObjectGetter(exec, originalObject, propertyName, slot); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSHTMLCollectionCustom.cpp b/WebCore/bindings/js/JSHTMLCollectionCustom.cpp new file mode 100644 index 0000000..2c44ab0 --- /dev/null +++ b/WebCore/bindings/js/JSHTMLCollectionCustom.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "JSHTMLCollection.h" + +#include "AtomicString.h" +#include "HTMLCollection.h" +#include "HTMLOptionsCollection.h" +#include "JSHTMLAllCollection.h" +#include "JSHTMLOptionsCollection.h" +#include "JSNamedNodesCollection.h" +#include "JSNode.h" +#include "Node.h" +#include "kjs_binding.h" +#include "kjs_html.h" +#include <wtf/Vector.h> + +using namespace KJS; + +namespace WebCore { + +static JSValue* getNamedItems(ExecState* exec, HTMLCollection* impl, const Identifier& propertyName) +{ + Vector<RefPtr<Node> > namedItems; + impl->namedItems(propertyName, namedItems); + + if (namedItems.isEmpty()) + return jsUndefined(); + + if (namedItems.size() == 1) + return toJS(exec, namedItems[0].get()); + + return new JSNamedNodesCollection(exec->lexicalGlobalObject()->objectPrototype(), namedItems); +} + +// HTMLCollections are strange objects, they support both get and call, +// so that document.forms.item(0) and document.forms(0) both work. +JSValue* JSHTMLCollection::callAsFunction(ExecState* exec, JSObject*, const List& args) +{ + if (args.size() < 1) + return jsUndefined(); + + // Do not use thisObj here. It can be the JSHTMLDocument, in the document.forms(i) case. + HTMLCollection* collection = impl(); + + // Also, do we need the TypeError test here ? + + if (args.size() == 1) { + // Support for document.all(<index>) etc. + bool ok; + UString string = args[0]->toString(exec); + unsigned index = string.toUInt32(&ok, false); + if (ok) + return toJS(exec, collection->item(index)); + + // Support for document.images('<name>') etc. + return getNamedItems(exec, collection, Identifier(string)); + } + + // The second arg, if set, is the index of the item we want + bool ok; + UString string = args[0]->toString(exec); + unsigned index = args[1]->toString(exec).toUInt32(&ok, false); + if (ok) { + String pstr = string; + Node* node = collection->namedItem(pstr); + while (node) { + if (!index) + return toJS(exec, node); + node = collection->nextNamedItem(pstr); + --index; + } + } + + return jsUndefined(); +} + +bool JSHTMLCollection::implementsCall() const +{ + return true; +} + +bool JSHTMLCollection::canGetItemsForName(ExecState* exec, HTMLCollection* thisObj, const Identifier& propertyName) +{ + return !getNamedItems(exec, thisObj, propertyName)->isUndefined(); +} + +JSValue* JSHTMLCollection::nameGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot) +{ + JSHTMLCollection* thisObj = static_cast<JSHTMLCollection*>(slot.slotBase()); + return getNamedItems(exec, thisObj->impl(), propertyName); +} + +JSValue* JSHTMLCollection::item(ExecState* exec, const List& args) +{ + bool ok; + uint32_t index = args[0]->toString(exec).toUInt32(&ok, false); + if (ok) + return toJS(exec, impl()->item(index)); + return getNamedItems(exec, impl(), Identifier(args[0]->toString(exec))); +} + +JSValue* JSHTMLCollection::namedItem(ExecState* exec, const List& args) +{ + return getNamedItems(exec, impl(), Identifier(args[0]->toString(exec))); +} + +JSValue* toJS(ExecState* exec, HTMLCollection* collection) +{ + if (!collection) + return jsNull(); + + DOMObject* ret = ScriptInterpreter::getDOMObject(collection); + + if (ret) + return ret; + + switch (collection->type()) { + case HTMLCollection::SelectOptions: + ret = new JSHTMLOptionsCollection(JSHTMLOptionsCollectionPrototype::self(exec), static_cast<HTMLOptionsCollection*>(collection)); + break; + case HTMLCollection::DocAll: + ret = new JSHTMLAllCollection(JSHTMLCollectionPrototype::self(exec), static_cast<HTMLCollection*>(collection)); + break; + default: + ret = new JSHTMLCollection(JSHTMLCollectionPrototype::self(exec), static_cast<HTMLCollection*>(collection)); + break; + } + + ScriptInterpreter::putDOMObject(collection, ret); + return ret; +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSHTMLDocumentCustom.cpp b/WebCore/bindings/js/JSHTMLDocumentCustom.cpp new file mode 100644 index 0000000..5455617 --- /dev/null +++ b/WebCore/bindings/js/JSHTMLDocumentCustom.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSHTMLDocument.h" + +#include "Frame.h" +#include "HTMLBodyElement.h" +#include "HTMLCollection.h" +#include "HTMLDocument.h" +#include "HTMLElement.h" +#include "HTMLIFrameElement.h" +#include "HTMLNames.h" +#include "JSHTMLCollection.h" +#include "kjs_html.h" +#include "kjs_window.h" + +namespace WebCore { + +using namespace KJS; +using namespace HTMLNames; + +bool JSHTMLDocument::canGetItemsForName(ExecState*, HTMLDocument* doc, const Identifier& propertyName) +{ + return doc->hasNamedItem(propertyName) || doc->hasDocExtraNamedItem(propertyName); +} + +JSValue* JSHTMLDocument::nameGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot) +{ + JSHTMLDocument* thisObj = static_cast<JSHTMLDocument*>(slot.slotBase()); + HTMLDocument* doc = static_cast<HTMLDocument*>(thisObj->impl()); + + String name = propertyName; + RefPtr<HTMLCollection> collection = doc->documentNamedItems(name); + + unsigned length = collection->length(); + if (!length) + return jsUndefined(); + + if (length == 1) { + Node* node = collection->firstItem(); + + Frame* frame; + if (node->hasTagName(iframeTag) && (frame = static_cast<HTMLIFrameElement*>(node)->contentFrame())) + return KJS::Window::retrieve(frame); + + return toJS(exec, node); + } + + return toJS(exec, collection.get()); +} + +// Custom attributes + +JSValue* JSHTMLDocument::all(ExecState* exec) const +{ + // If "all" has been overwritten, return the overwritten value + if (JSValue* v = getDirect("all")) + return v; + + return toJS(exec, static_cast<HTMLDocument*>(impl())->all().get()); +} + +void JSHTMLDocument::setAll(ExecState*, JSValue* value) +{ + // Add "all" to the property map. + putDirect("all", value); +} + +// Custom functions + +JSValue* JSHTMLDocument::open(ExecState* exec, const List& args) +{ + // For compatibility with other browsers, pass open calls with more than 2 parameters to the window. + if (args.size() > 2) { + Frame* frame = static_cast<HTMLDocument*>(impl())->frame(); + if (frame) { + KJS::Window* window = KJS::Window::retrieveWindow(frame); + if (window) { + JSObject* functionObject = window->get(exec, "open")->getObject(); + if (!functionObject || !functionObject->implementsCall()) + return throwError(exec, TypeError); + return functionObject->call(exec, window, args); + } + } + return jsUndefined(); + } + + // In the case of two parameters or fewer, do a normal document open. + static_cast<HTMLDocument*>(impl())->open(); + return jsUndefined(); +} + +static String writeHelper(ExecState* exec, const List& args) +{ + // DOM only specifies single string argument, but NS & IE allow multiple + // or no arguments. + String str = ""; + for (unsigned int i = 0; i < args.size(); ++i) + str += args[i]->toString(exec); + return str; +} + +JSValue* JSHTMLDocument::write(ExecState* exec, const List& args) +{ + static_cast<HTMLDocument*>(impl())->write(writeHelper(exec, args)); + return jsUndefined(); +} + +JSValue* JSHTMLDocument::writeln(ExecState* exec, const List& args) +{ + static_cast<HTMLDocument*>(impl())->write(writeHelper(exec, args) + "\n"); + return jsUndefined(); +} + +JSValue* JSHTMLDocument::clear(ExecState*, const List&) +{ + // even IE doesn't support this one... + // static_cast<HTMLDocument*>(impl())->clear(); + return jsUndefined(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSHTMLElementCustom.cpp b/WebCore/bindings/js/JSHTMLElementCustom.cpp new file mode 100644 index 0000000..755277a --- /dev/null +++ b/WebCore/bindings/js/JSHTMLElementCustom.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSHTMLElement.h" + +#include "Document.h" +#include "HTMLFormElement.h" +#include "kjs_dom.h" + +namespace WebCore { + +using namespace KJS; + +void JSHTMLElement::pushEventHandlerScope(ExecState* exec, ScopeChain& scope) const +{ + HTMLElement* element = impl(); + + // The document is put on first, fall back to searching it only after the element and form. + scope.push(static_cast<JSObject*>(toJS(exec, element->ownerDocument()))); + + // The form is next, searched before the document, but after the element itself. + if (HTMLFormElement* form = element->form()) + scope.push(static_cast<JSObject*>(toJS(exec, form))); + + // The element is on top, searched first. + scope.push(static_cast<JSObject*>(toJS(exec, element))); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSHTMLElementWrapperFactory.cpp b/WebCore/bindings/js/JSHTMLElementWrapperFactory.cpp new file mode 100644 index 0000000..1202e6c --- /dev/null +++ b/WebCore/bindings/js/JSHTMLElementWrapperFactory.cpp @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "JSHTMLElementWrapperFactory.h" + +#include "HTMLAnchorElement.h" +#include "HTMLAppletElement.h" +#include "HTMLAreaElement.h" +#include "HTMLAudioElement.h" +#include "HTMLBRElement.h" +#include "HTMLBaseElement.h" +#include "HTMLBaseFontElement.h" +#include "HTMLBlockquoteElement.h" +#include "HTMLBodyElement.h" +#include "HTMLButtonElement.h" +#include "HTMLCanvasElement.h" +#include "HTMLDListElement.h" +#include "HTMLDirectoryElement.h" +#include "HTMLDivElement.h" +#include "HTMLEmbedElement.h" +#include "HTMLFieldSetElement.h" +#include "HTMLFontElement.h" +#include "HTMLFormElement.h" +#include "HTMLFrameElement.h" +#include "HTMLFrameSetElement.h" +#include "HTMLHRElement.h" +#include "HTMLHeadElement.h" +#include "HTMLHeadingElement.h" +#include "HTMLHtmlElement.h" +#include "HTMLIFrameElement.h" +#include "HTMLImageElement.h" +#include "HTMLInputElement.h" +#include "HTMLIsIndexElement.h" +#include "HTMLLIElement.h" +#include "HTMLLabelElement.h" +#include "HTMLLegendElement.h" +#include "HTMLLinkElement.h" +#include "HTMLMapElement.h" +#include "HTMLMarqueeElement.h" +#include "HTMLMenuElement.h" +#include "HTMLMetaElement.h" +#include "HTMLModElement.h" +#include "HTMLOListElement.h" +#include "HTMLObjectElement.h" +#include "HTMLOptGroupElement.h" +#include "HTMLOptionElement.h" +#include "HTMLParagraphElement.h" +#include "HTMLParamElement.h" +#include "HTMLPreElement.h" +#include "HTMLQuoteElement.h" +#include "HTMLScriptElement.h" +#include "HTMLSelectElement.h" +#include "HTMLSourceElement.h" +#include "HTMLStyleElement.h" +#include "HTMLTableCaptionElement.h" +#include "HTMLTableCellElement.h" +#include "HTMLTableColElement.h" +#include "HTMLTableElement.h" +#include "HTMLTableRowElement.h" +#include "HTMLTableSectionElement.h" +#include "HTMLTextAreaElement.h" +#include "HTMLTitleElement.h" +#include "HTMLUListElement.h" +#include "HTMLVideoElement.h" + +#include "HTMLNames.h" + +#include "JSHTMLAnchorElement.h" +#include "JSHTMLAppletElement.h" +#include "JSHTMLAreaElement.h" +#include "JSHTMLBRElement.h" +#include "JSHTMLBaseElement.h" +#include "JSHTMLBaseFontElement.h" +#include "JSHTMLBlockquoteElement.h" +#include "JSHTMLBodyElement.h" +#include "JSHTMLButtonElement.h" +#include "JSHTMLCanvasElement.h" +#include "JSHTMLDListElement.h" +#include "JSHTMLDirectoryElement.h" +#include "JSHTMLDivElement.h" +#include "JSHTMLEmbedElement.h" +#include "JSHTMLFieldSetElement.h" +#include "JSHTMLFontElement.h" +#include "JSHTMLFormElement.h" +#include "JSHTMLFrameElement.h" +#include "JSHTMLFrameSetElement.h" +#include "JSHTMLHRElement.h" +#include "JSHTMLHeadElement.h" +#include "JSHTMLHeadingElement.h" +#include "JSHTMLHtmlElement.h" +#include "JSHTMLIFrameElement.h" +#include "JSHTMLImageElement.h" +#include "JSHTMLInputElement.h" +#include "JSHTMLIsIndexElement.h" +#include "JSHTMLLIElement.h" +#include "JSHTMLLabelElement.h" +#include "JSHTMLLegendElement.h" +#include "JSHTMLLinkElement.h" +#include "JSHTMLMapElement.h" +#include "JSHTMLMarqueeElement.h" +#include "JSHTMLMenuElement.h" +#include "JSHTMLMetaElement.h" +#include "JSHTMLModElement.h" +#include "JSHTMLOListElement.h" +#include "JSHTMLObjectElement.h" +#include "JSHTMLOptGroupElement.h" +#include "JSHTMLOptionElement.h" +#include "JSHTMLParagraphElement.h" +#include "JSHTMLParamElement.h" +#include "JSHTMLPreElement.h" +#include "JSHTMLQuoteElement.h" +#include "JSHTMLScriptElement.h" +#include "JSHTMLSelectElement.h" +#include "JSHTMLStyleElement.h" +#include "JSHTMLTableCaptionElement.h" +#include "JSHTMLTableCellElement.h" +#include "JSHTMLTableColElement.h" +#include "JSHTMLTableElement.h" +#include "JSHTMLTableRowElement.h" +#include "JSHTMLTableSectionElement.h" +#include "JSHTMLTextAreaElement.h" +#include "JSHTMLTitleElement.h" +#include "JSHTMLUListElement.h" + +#if ENABLE(VIDEO) +#include "JSHTMLAudioElement.h" +#include "JSHTMLSourceElement.h" +#include "JSHTMLVideoElement.h" +#endif + +#include "kjs_html.h" + +using namespace KJS; + +// FIXME: Eventually this file should be autogenerated, just like HTMLNames, HTMLElementFactory, etc. + +namespace WebCore { + +using namespace HTMLNames; + +typedef JSNode* (*CreateHTMLElementWrapperFunction)(ExecState*, PassRefPtr<HTMLElement>); + +#define FOR_EACH_TAG(macro) \ + macro(a, Anchor) \ + macro(applet, Applet) \ + macro(area, Area) \ + macro(base, Base) \ + macro(basefont, BaseFont) \ + macro(blockquote, Blockquote) \ + macro(body, Body) \ + macro(br, BR) \ + macro(button, Button) \ + macro(canvas, Canvas) \ + macro(caption, TableCaption) \ + macro(col, TableCol) \ + macro(del, Mod) \ + macro(dir, Directory) \ + macro(div, Div) \ + macro(dl, DList) \ + macro(embed, Embed) \ + macro(fieldset, FieldSet) \ + macro(font, Font) \ + macro(form, Form) \ + macro(frame, Frame) \ + macro(frameset, FrameSet) \ + macro(h1, Heading) \ + macro(head, Head) \ + macro(hr, HR) \ + macro(html, Html) \ + macro(iframe, IFrame) \ + macro(img, Image) \ + macro(input, Input) \ + macro(isindex, IsIndex) \ + macro(label, Label) \ + macro(legend, Legend) \ + macro(li, LI) \ + macro(link, Link) \ + macro(map, Map) \ + macro(marquee, Marquee) \ + macro(menu, Menu) \ + macro(meta, Meta) \ + macro(object, Object) \ + macro(ol, OList) \ + macro(optgroup, OptGroup) \ + macro(option, Option) \ + macro(p, Paragraph) \ + macro(param, Param) \ + macro(pre, Pre) \ + macro(q, Quote) \ + macro(script, Script) \ + macro(select, Select) \ + macro(style, Style) \ + macro(table, Table) \ + macro(tbody, TableSection) \ + macro(td, TableCell) \ + macro(textarea, TextArea) \ + macro(tr, TableRow) \ + macro(title, Title) \ + macro(ul, UList) \ + // end of macro + +#define FOR_EACH_MEDIA_TAG(macro) \ + macro(audio, Audio) \ + macro(source, Source) \ + macro(video, Video) \ + // end of macro + +#define CREATE_WRAPPER_FUNCTION(tag, name) \ +static JSNode* create##name##Wrapper(ExecState* exec, PassRefPtr<HTMLElement> element) \ +{ \ + return new JSHTML##name##Element(JSHTML##name##ElementPrototype::self(exec), static_cast<HTML##name##Element*>(element.get())); \ +} +#define CREATE_MEDIA_WRAPPER_FUNCTION(tag, name) \ +static JSNode* create##name##Wrapper(ExecState* exec, PassRefPtr<HTMLElement> element) \ +{ \ + if (!MediaPlayer::isAvailable()) \ + return new JSHTMLElement(JSHTMLElementPrototype::self(exec), element.get()); \ + return new JSHTML##name##Element(JSHTML##name##ElementPrototype::self(exec), static_cast<HTML##name##Element*>(element.get())); \ +} +FOR_EACH_TAG(CREATE_WRAPPER_FUNCTION) +#if ENABLE(VIDEO) + FOR_EACH_MEDIA_TAG(CREATE_MEDIA_WRAPPER_FUNCTION) +#endif +#undef CREATE_WRAPPER_FUNCTION + +JSNode* createJSHTMLWrapper(ExecState* exec, PassRefPtr<HTMLElement> element) +{ + static HashMap<AtomicStringImpl*, CreateHTMLElementWrapperFunction> map; + if (map.isEmpty()) { +#define ADD_TO_HASH_MAP(tag, name) map.set(tag##Tag.localName().impl(), create##name##Wrapper); +FOR_EACH_TAG(ADD_TO_HASH_MAP) +#if ENABLE(VIDEO) +FOR_EACH_MEDIA_TAG(ADD_TO_HASH_MAP) +#endif +#undef ADD_TO_HASH_MAP + map.set(colgroupTag.localName().impl(), createTableColWrapper); + map.set(h2Tag.localName().impl(), createHeadingWrapper); + map.set(h3Tag.localName().impl(), createHeadingWrapper); + map.set(h4Tag.localName().impl(), createHeadingWrapper); + map.set(h5Tag.localName().impl(), createHeadingWrapper); + map.set(h6Tag.localName().impl(), createHeadingWrapper); + map.set(imageTag.localName().impl(), createImageWrapper); + map.set(insTag.localName().impl(), createModWrapper); + map.set(keygenTag.localName().impl(), createSelectWrapper); + map.set(listingTag.localName().impl(), createPreWrapper); + map.set(tfootTag.localName().impl(), createTableSectionWrapper); + map.set(thTag.localName().impl(), createTableCellWrapper); + map.set(theadTag.localName().impl(), createTableSectionWrapper); + map.set(xmpTag.localName().impl(), createPreWrapper); + } + CreateHTMLElementWrapperFunction createWrapperFunction = map.get(element->localName().impl()); + if (createWrapperFunction) + return createWrapperFunction(exec, element); + return new JSHTMLElement(JSHTMLElementPrototype::self(exec), element.get()); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSHTMLElementWrapperFactory.h b/WebCore/bindings/js/JSHTMLElementWrapperFactory.h new file mode 100644 index 0000000..8e8bffa --- /dev/null +++ b/WebCore/bindings/js/JSHTMLElementWrapperFactory.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All ri + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef JSHTMLElementWrapperFactory_h +#define JSHTMLElementWrapperFactory_h + +#include <wtf/Forward.h> + +namespace KJS { + class ExecState; +} + +namespace WebCore { + + class JSNode; + class HTMLElement; + + JSNode* createJSHTMLWrapper(KJS::ExecState*, PassRefPtr<HTMLElement>); + +} + +#endif diff --git a/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp b/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp new file mode 100644 index 0000000..1224f2c --- /dev/null +++ b/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSHTMLEmbedElement.h" + +#include "HTMLEmbedElement.h" +#include "kjs_dom.h" +#include "kjs_html.h" + +namespace WebCore { + +using namespace KJS; + +bool JSHTMLEmbedElement::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + return runtimeObjectCustomGetOwnPropertySlot(exec, propertyName, slot, this, static_cast<HTMLElement*>(impl())); +} + +bool JSHTMLEmbedElement::customPut(ExecState* exec, const Identifier& propertyName, JSValue* value) +{ + return runtimeObjectCustomPut(exec, propertyName, value, static_cast<HTMLElement*>(impl())); +} + +bool JSHTMLEmbedElement::implementsCall() const +{ + return runtimeObjectImplementsCall(static_cast<HTMLElement*>(impl())); +} + +JSValue* JSHTMLEmbedElement::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args) +{ + return runtimeObjectCallAsFunction(exec, thisObj, args, static_cast<HTMLElement*>(impl())); +} + +bool JSHTMLEmbedElement::canGetItemsForName(ExecState*, HTMLEmbedElement*, const Identifier& propertyName) +{ + return propertyName == "__apple_runtime_object"; +} + +JSValue* JSHTMLEmbedElement::nameGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot) +{ + return runtimeObjectGetter(exec, originalObject, propertyName, slot); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSHTMLFormElementCustom.cpp b/WebCore/bindings/js/JSHTMLFormElementCustom.cpp new file mode 100644 index 0000000..8e24618 --- /dev/null +++ b/WebCore/bindings/js/JSHTMLFormElementCustom.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSHTMLFormElement.h" + +#include "HTMLCollection.h" +#include "HTMLFormElement.h" +#include "JSNamedNodesCollection.h" +#include "kjs_dom.h" + +using namespace KJS; + +namespace WebCore { + +bool JSHTMLFormElement::canGetItemsForName(ExecState* exec, HTMLFormElement* form, const Identifier& propertyName) +{ + Vector<RefPtr<Node> > namedItems; + form->getNamedElements(propertyName, namedItems); + return namedItems.size(); +} + +JSValue* JSHTMLFormElement::nameGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot) +{ + HTMLFormElement* form = static_cast<HTMLFormElement*>(static_cast<JSHTMLElement*>(slot.slotBase())->impl()); + + Vector<RefPtr<Node> > namedItems; + form->getNamedElements(propertyName, namedItems); + + if (namedItems.size() == 1) + return toJS(exec, namedItems[0].get()); + if (namedItems.size() > 1) + return new JSNamedNodesCollection(exec->lexicalGlobalObject()->objectPrototype(), namedItems); + return jsUndefined(); +} + +} diff --git a/WebCore/bindings/js/JSHTMLFrameElementCustom.cpp b/WebCore/bindings/js/JSHTMLFrameElementCustom.cpp new file mode 100644 index 0000000..b5b6370 --- /dev/null +++ b/WebCore/bindings/js/JSHTMLFrameElementCustom.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSHTMLFrameElement.h" + +#include "CSSHelper.h" +#include "HTMLFrameElement.h" + +using namespace KJS; + +namespace WebCore { + +static inline bool allowSettingJavascriptURL(ExecState* exec, HTMLFrameElement* imp, const String& value) +{ + if (protocolIs(parseURL(value), "javascript")) { + if (!checkNodeSecurity(exec, imp->contentDocument())) + return false; + } + return true; +} + +void JSHTMLFrameElement::setSrc(ExecState* exec, JSValue* value) +{ + HTMLFrameElement* imp = static_cast<HTMLFrameElement*>(impl()); + String srcValue = valueToStringWithNullCheck(exec, value); + + if (!allowSettingJavascriptURL(exec, imp, srcValue)) + return; + + imp->setSrc(srcValue); + return; +} + +void JSHTMLFrameElement::setLocation(ExecState* exec, JSValue* value) +{ + HTMLFrameElement* imp = static_cast<HTMLFrameElement*>(impl()); + String locationValue = valueToStringWithNullCheck(exec, value); + + if (!allowSettingJavascriptURL(exec, imp, locationValue)) + return; + + imp->setLocation(locationValue); + return; +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSHTMLFrameSetElementCustom.cpp b/WebCore/bindings/js/JSHTMLFrameSetElementCustom.cpp new file mode 100644 index 0000000..1e10dc2 --- /dev/null +++ b/WebCore/bindings/js/JSHTMLFrameSetElementCustom.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSHTMLFrameSetElement.h" + +#include "Document.h" +#include "HTMLFrameElement.h" +#include "HTMLFrameSetElement.h" +#include "HTMLNames.h" +#include "kjs_binding.h" +#include "kjs_window.h" + +namespace WebCore { + +using namespace KJS; +using namespace HTMLNames; + +bool JSHTMLFrameSetElement::canGetItemsForName(ExecState*, HTMLFrameSetElement* frameSet, const Identifier& propertyName) +{ + Node* frame = frameSet->children()->namedItem(propertyName); + return frame && frame->hasTagName(frameTag); +} + +JSValue* JSHTMLFrameSetElement::nameGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot) +{ + JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(slot.slotBase()); + HTMLElement* element = static_cast<HTMLElement*>(thisObj->impl()); + + Node* frame = element->children()->namedItem(propertyName); + if (Document* doc = static_cast<HTMLFrameElement*>(frame)->contentDocument()) { + if (KJS::Window* window = KJS::Window::retrieveWindow(doc->frame())) + return window; + } + + return jsUndefined(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSHTMLIFrameElementCustom.cpp b/WebCore/bindings/js/JSHTMLIFrameElementCustom.cpp new file mode 100644 index 0000000..309c932 --- /dev/null +++ b/WebCore/bindings/js/JSHTMLIFrameElementCustom.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSHTMLIFrameElement.h" + +#include "CSSHelper.h" +#include "HTMLIFrameElement.h" + +using namespace KJS; + +namespace WebCore { + +void JSHTMLIFrameElement::setSrc(ExecState* exec, JSValue* value) +{ + HTMLIFrameElement* imp = static_cast<HTMLIFrameElement*>(impl()); + + String srcValue = valueToStringWithNullCheck(exec, value); + + if (protocolIs(parseURL(srcValue), "javascript")) { + if (!checkNodeSecurity(exec, imp->contentDocument())) + return; + } + + imp->setSrc(srcValue); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSHTMLInputElementBase.cpp b/WebCore/bindings/js/JSHTMLInputElementBase.cpp new file mode 100644 index 0000000..f4b54b3 --- /dev/null +++ b/WebCore/bindings/js/JSHTMLInputElementBase.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "JSHTMLInputElementBase.h" + +#include "HTMLInputElement.h" + +#include "JSHTMLInputElementBaseTable.cpp" + +using namespace KJS; + +namespace WebCore { + +/* +@begin JSHTMLInputElementBaseTable 3 + selectionStart WebCore::JSHTMLInputElementBase::SelectionStart DontDelete + selectionEnd WebCore::JSHTMLInputElementBase::SelectionEnd DontDelete +@end +@begin JSHTMLInputElementBasePrototypeTable 0 +@end +@begin JSHTMLInputElementBaseFunctionTable 1 + setSelectionRange WebCore::jsHTMLInputElementBaseFunctionSetSelectionRange DontDelete|Function 2 +@end +*/ + +KJS_IMPLEMENT_PROTOTYPE("JSHTMLInputElementBase", JSHTMLInputElementBasePrototype) + +JSValue* jsHTMLInputElementBaseFunctionSetSelectionRange(ExecState* exec, JSObject* thisObj, const List& args) +{ + HTMLInputElement& input = *static_cast<HTMLInputElement*>(static_cast<JSHTMLInputElementBase*>(thisObj)->impl()); + input.setSelectionRange(args[0]->toInt32(exec), args[1]->toInt32(exec)); + return jsUndefined(); +} + +const ClassInfo JSHTMLInputElementBase::info = { "JSHTMLInputElementBase", &JSHTMLElement::info, &JSHTMLInputElementBaseTable }; + +JSHTMLInputElementBase::JSHTMLInputElementBase(KJS::JSObject* prototype, PassRefPtr<HTMLInputElement> e) + : JSHTMLElement(prototype, e.get()) +{ +} + +bool JSHTMLInputElementBase::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + HTMLInputElement& input = *static_cast<HTMLInputElement*>(impl()); + + // if this element doesn't support selection, we have nothing to do, try our parent + if (!input.canHaveSelection()) + return JSHTMLElement::getOwnPropertySlot(exec, propertyName, slot); + + // otherwise, do our own function lookup on our function table + const HashEntry* entry = Lookup::findEntry(&JSHTMLInputElementBaseFunctionTable, propertyName); + if (entry && (entry->attr & KJS::Function) && entry->value.functionValue == jsHTMLInputElementBaseFunctionSetSelectionRange) { + slot.setStaticEntry(this, entry, staticFunctionGetter); + return true; + } + ASSERT(!entry); + + // finally try value lookup or walk the parent chain + return getStaticValueSlot<JSHTMLInputElementBase, JSHTMLElement>(exec, &JSHTMLInputElementBaseTable, this, propertyName, slot); +} + +JSValue* JSHTMLInputElementBase::getValueProperty(ExecState* exec, int token) const +{ + HTMLInputElement& input = *static_cast<HTMLInputElement*>(impl()); + ASSERT(input.canHaveSelection()); + switch (token) { + case SelectionStart: + return jsNumber(input.selectionStart()); + case SelectionEnd: + return jsNumber(input.selectionEnd()); + } + ASSERT_NOT_REACHED(); + return jsUndefined(); +} + +void JSHTMLInputElementBase::put(ExecState* exec, const Identifier& propertyName, JSValue* value) +{ + lookupPut<JSHTMLInputElementBase, JSHTMLElement>(exec, propertyName, value, &JSHTMLInputElementBaseTable, this); +} + +void JSHTMLInputElementBase::putValueProperty(ExecState* exec, int token, JSValue* value) +{ + HTMLInputElement& input = *static_cast<HTMLInputElement*>(impl()); + ASSERT(input.canHaveSelection()); + switch (token) { + case SelectionStart: + input.setSelectionStart(value->toInt32(exec)); + return; + case SelectionEnd: + input.setSelectionEnd(value->toInt32(exec)); + return; + } + ASSERT_NOT_REACHED(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSHTMLInputElementBase.h b/WebCore/bindings/js/JSHTMLInputElementBase.h new file mode 100644 index 0000000..cb90e07 --- /dev/null +++ b/WebCore/bindings/js/JSHTMLInputElementBase.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef JSHTMLInputElementBase_h +#define JSHTMLInputElementBase_h + +#include "JSHTMLElement.h" +#include "kjs_binding.h" +#include "kjs_html.h" + +namespace WebCore { + + class HTMLInputElement; + + KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(JSHTMLInputElementBasePrototype, JSHTMLElementPrototype) + + class JSHTMLInputElementBase : public JSHTMLElement { + public: + JSHTMLInputElementBase(KJS::JSObject* prototype, PassRefPtr<HTMLInputElement>); + + virtual bool getOwnPropertySlot(KJS::ExecState*, const KJS::Identifier&, KJS::PropertySlot&); + KJS::JSValue* getValueProperty(KJS::ExecState*, int token) const; + virtual void put(KJS::ExecState*, const KJS::Identifier& propertyName, JSValue*); + void putValueProperty(KJS::ExecState*, int token, KJS::JSValue*); + virtual const KJS::ClassInfo* classInfo() const { return &info; } + static const KJS::ClassInfo info; + enum { SelectionStart, SelectionEnd }; + }; + + // SetSelectionRange is implemented on the class instead of on the prototype + // to make it easier to enable/disable lookup of the function based on input type. + KJS::JSValue* jsHTMLInputElementBaseFunctionSetSelectionRange(KJS::ExecState*, KJS::JSObject*, const KJS::List&); + +} // namespace WebCore + +#endif // JSHTMLInputElementBase_h diff --git a/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp b/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp new file mode 100644 index 0000000..83e9b0d --- /dev/null +++ b/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSHTMLObjectElement.h" + +#include "HTMLObjectElement.h" +#include "kjs_dom.h" +#include "kjs_html.h" + +namespace WebCore { + +using namespace KJS; + +bool JSHTMLObjectElement::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + return runtimeObjectCustomGetOwnPropertySlot(exec, propertyName, slot, this, static_cast<HTMLElement*>(impl())); +} + +bool JSHTMLObjectElement::customPut(ExecState* exec, const Identifier& propertyName, JSValue* value) +{ + return runtimeObjectCustomPut(exec, propertyName, value, static_cast<HTMLElement*>(impl())); +} + +bool JSHTMLObjectElement::implementsCall() const +{ + return runtimeObjectImplementsCall(static_cast<HTMLElement*>(impl())); +} + +JSValue* JSHTMLObjectElement::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args) +{ + return runtimeObjectCallAsFunction(exec, thisObj, args, static_cast<HTMLElement*>(impl())); +} + +bool JSHTMLObjectElement::canGetItemsForName(ExecState*, HTMLObjectElement*, const Identifier& propertyName) +{ + return propertyName == "__apple_runtime_object"; +} + +JSValue* JSHTMLObjectElement::nameGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot) +{ + return runtimeObjectGetter(exec, originalObject, propertyName, slot); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSHTMLOptionElementConstructor.cpp b/WebCore/bindings/js/JSHTMLOptionElementConstructor.cpp new file mode 100644 index 0000000..551854a --- /dev/null +++ b/WebCore/bindings/js/JSHTMLOptionElementConstructor.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "JSHTMLOptionElementConstructor.h" + +#include "Document.h" +#include "HTMLOptionElement.h" +#include "JSHTMLOptionElement.h" +#include "Text.h" + +using namespace KJS; + +namespace WebCore { + +JSHTMLOptionElementConstructor::JSHTMLOptionElementConstructor(ExecState* exec, Document* document) + : DOMObject(exec->lexicalGlobalObject()->objectPrototype()) + , m_document(document) +{ + putDirect(exec->propertyNames().length, jsNumber(4), ReadOnly|DontDelete|DontEnum); +} + +bool JSHTMLOptionElementConstructor::implementsConstruct() const +{ + return true; +} + +JSObject* JSHTMLOptionElementConstructor::construct(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + + RefPtr<HTMLOptionElement> element = static_pointer_cast<HTMLOptionElement>(m_document->createElement("option", ec)); + if (element) { + RefPtr<Text> text = m_document->createTextNode(""); + if (!args[0]->isUndefined()) + text->setData(args[0]->toString(exec), ec); + if (ec == 0) + element->appendChild(text.release(), ec); + if (ec == 0 && !args[1]->isUndefined()) + element->setValue(args[1]->toString(exec)); + if (ec == 0) + element->setDefaultSelected(args[2]->toBoolean(exec)); + if (ec == 0) + element->setSelected(args[3]->toBoolean(exec)); + } + + setDOMException(exec, ec); + if (ec || !element) + return 0; + + return static_cast<JSObject*>(toJS(exec, element.release())); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSHTMLOptionElementConstructor.h b/WebCore/bindings/js/JSHTMLOptionElementConstructor.h new file mode 100644 index 0000000..47a95c7 --- /dev/null +++ b/WebCore/bindings/js/JSHTMLOptionElementConstructor.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef JSHTMLOptionElementConstructor_h +#define JSHTMLOptionElementConstructor_h + +#include "kjs_binding.h" +#include <wtf/RefPtr.h> + +namespace WebCore { + + class JSHTMLOptionElementConstructor : public DOMObject { + public: + JSHTMLOptionElementConstructor(KJS::ExecState*, Document*); + virtual bool implementsConstruct() const; + virtual KJS::JSObject* construct(KJS::ExecState*, const KJS::List& args); + private: + RefPtr<Document> m_document; + }; + +} + +#endif diff --git a/WebCore/bindings/js/JSHTMLOptionsCollectionCustom.cpp b/WebCore/bindings/js/JSHTMLOptionsCollectionCustom.cpp new file mode 100644 index 0000000..c0daf19 --- /dev/null +++ b/WebCore/bindings/js/JSHTMLOptionsCollectionCustom.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "JSHTMLOptionsCollection.h" + +#include "ExceptionCode.h" +#include "HTMLNames.h" +#include "HTMLOptionElement.h" +#include "HTMLOptionsCollection.h" +#include "HTMLSelectElement.h" +#include "JSHTMLOptionElement.h" +#include "JSHTMLSelectElement.h" +#include "JSHTMLSelectElementCustom.h" + +#include <wtf/MathExtras.h> + +using namespace KJS; + +namespace WebCore { + +JSValue* JSHTMLOptionsCollection::length(ExecState* exec) const +{ + HTMLOptionsCollection* imp = static_cast<HTMLOptionsCollection*>(impl()); + return jsNumber(imp->length()); +} + +void JSHTMLOptionsCollection::setLength(ExecState* exec, JSValue* value) +{ + HTMLOptionsCollection* imp = static_cast<HTMLOptionsCollection*>(impl()); + ExceptionCode ec = 0; + unsigned newLength = 0; + double lengthValue = value->toNumber(exec); + if (!isnan(lengthValue) && !isinf(lengthValue)) { + if (lengthValue < 0.0) + ec = INDEX_SIZE_ERR; + else if (lengthValue > static_cast<double>(UINT_MAX)) + newLength = UINT_MAX; + else + newLength = static_cast<unsigned>(lengthValue); + } + if (!ec) + imp->setLength(newLength, ec); + setDOMException(exec, ec); +} + +void JSHTMLOptionsCollection::indexSetter(ExecState* exec, unsigned index, JSValue* value) +{ + HTMLOptionsCollection* imp = static_cast<HTMLOptionsCollection*>(impl()); + HTMLSelectElement* base = static_cast<HTMLSelectElement*>(imp->base()); + selectIndexSetter(base, exec, index, value); +} + +JSValue* JSHTMLOptionsCollection::add(ExecState* exec, const List& args) +{ + HTMLOptionsCollection* imp = static_cast<HTMLOptionsCollection*>(impl()); + HTMLOptionElement* option = toHTMLOptionElement(args[0]); + ExceptionCode ec = 0; + if (args.size() < 2) + imp->add(option, ec); + else { + bool ok; + int index = args[1]->toInt32(exec, ok); + if (exec->hadException()) + return jsUndefined(); + if (!ok) + ec = TYPE_MISMATCH_ERR; + else + imp->add(option, index, ec); + } + setDOMException(exec, ec); + return jsUndefined(); +} + +JSValue* JSHTMLOptionsCollection::remove(ExecState* exec, const List& args) +{ + HTMLOptionsCollection* imp = static_cast<HTMLOptionsCollection*>(impl()); + JSHTMLSelectElement* base = static_cast<JSHTMLSelectElement*>(toJS(exec, imp->base())); + return base->remove(exec, args); +} + +} diff --git a/WebCore/bindings/js/JSHTMLSelectElementCustom.cpp b/WebCore/bindings/js/JSHTMLSelectElementCustom.cpp new file mode 100644 index 0000000..9688cfe --- /dev/null +++ b/WebCore/bindings/js/JSHTMLSelectElementCustom.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2007 Apple, Inc. + * Copyright (C) 2007 Alexey Proskuryakov (ap@webkit.org) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "JSHTMLSelectElementCustom.h" + +#include "ExceptionCode.h" +#include "HTMLNames.h" +#include "HTMLOptionElement.h" +#include "HTMLSelectElement.h" +#include "JSHTMLOptionElement.h" +#include "kjs_html.h" + +namespace WebCore { + +using namespace KJS; +using namespace HTMLNames; + +JSValue* JSHTMLSelectElement::remove(ExecState* exec, const List& args) +{ + HTMLSelectElement& select = *static_cast<HTMLSelectElement*>(impl()); + + // we support both options index and options objects + HTMLElement* element = toHTMLElement(args[0]); + if (element && element->hasTagName(optionTag)) + select.remove(static_cast<HTMLOptionElement*>(element)->index()); + else + select.remove(args[0]->toInt32(exec)); + + return jsUndefined(); +} + +void selectIndexSetter(HTMLSelectElement* select, KJS::ExecState* exec, unsigned index, KJS::JSValue* value) +{ + if (value->isUndefinedOrNull()) + select->remove(index); + else { + ExceptionCode ec = 0; + HTMLOptionElement* option = toHTMLOptionElement(value); + if (!option) + ec = TYPE_MISMATCH_ERR; + else + select->setOption(index, option, ec); + setDOMException(exec, ec); + } +} + +void JSHTMLSelectElement::indexSetter(KJS::ExecState* exec, unsigned index, KJS::JSValue* value) +{ + selectIndexSetter(static_cast<HTMLSelectElement*>(impl()), exec, index, value); +} + +} diff --git a/WebCore/bindings/js/JSHTMLSelectElementCustom.h b/WebCore/bindings/js/JSHTMLSelectElementCustom.h new file mode 100644 index 0000000..b6f08c7 --- /dev/null +++ b/WebCore/bindings/js/JSHTMLSelectElementCustom.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSHTMLSelectElementCustom_h +#define JSHTMLSelectElementCustom_h + +#include "JSHTMLSelectElement.h" + +namespace WebCore { + +void selectIndexSetter(HTMLSelectElement*, KJS::ExecState*, unsigned index, KJS::JSValue*); + +} + +#endif diff --git a/WebCore/bindings/js/JSHistoryCustom.cpp b/WebCore/bindings/js/JSHistoryCustom.cpp new file mode 100644 index 0000000..0e5d0d0 --- /dev/null +++ b/WebCore/bindings/js/JSHistoryCustom.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSHistory.h" + +#include "Frame.h" +#include "History.h" +#include "kjs_window.h" + +using namespace KJS; + +namespace WebCore { + +bool JSHistory::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + // When accessing History cross-domain, functions are always the native built-in ones. + // See JSDOMWindow::customGetOwnPropertySlot for additional details. + + // Our custom code is only needed to implement the Window cross-domain scheme, so if access is + // allowed, return false so the normal lookup will take place. + String message; + if (allowsAccessFromFrame(exec, impl()->frame(), message)) + return false; + + // Check for the few functions that we allow, even when called cross-domain. + const HashEntry* entry = Lookup::findEntry(JSHistoryPrototype::info.propHashTable, propertyName); + if (entry) { + // Allow access to back(), forward() and go() from any frame. + if ((entry->attr & Function) + && (entry->value.functionValue == jsHistoryPrototypeFunctionBack + || entry->value.functionValue == jsHistoryPrototypeFunctionForward + || entry->value.functionValue == jsHistoryPrototypeFunctionGo)) { + slot.setStaticEntry(this, entry, nonCachingStaticFunctionGetter); + return true; + } + } else { + // Allow access to toString() cross-domain, but always Object.toString. + if (propertyName == exec->propertyNames().toString) { + slot.setCustom(this, objectToStringFunctionGetter); + return true; + } + } + + printErrorMessageForFrame(impl()->frame(), message); + slot.setUndefined(this); + return true; +} + +bool JSHistory::customPut(ExecState* exec, const Identifier& propertyName, JSValue* value) +{ + // Only allow putting by frames in the same origin. + if (!allowsAccessFromFrame(exec, impl()->frame())) + return true; + return false; +} + +bool JSHistory::deleteProperty(ExecState* exec, const Identifier& propertyName) +{ + // Only allow deleting by frames in the same origin. + if (!allowsAccessFromFrame(exec, impl()->frame())) + return false; + return Base::deleteProperty(exec, propertyName); +} + +bool JSHistory::customGetPropertyNames(ExecState* exec, PropertyNameArray&) +{ + // Only allow the history object to enumerated by frames in the same origin. + if (!allowsAccessFromFrame(exec, impl()->frame())) + return true; + return false; +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSLocation.cpp b/WebCore/bindings/js/JSLocation.cpp new file mode 100644 index 0000000..2fc1a34 --- /dev/null +++ b/WebCore/bindings/js/JSLocation.cpp @@ -0,0 +1,313 @@ +/* + * Copyright (C) 2000 Harri Porten (porten@kde.org) + * Copyright (C) 2006 Jon Shier (jshier@iastate.edu) + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reseved. + * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#include "config.h" +#include "JSLocation.h" + +#include "DOMWindow.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "kjs_proxy.h" +#include "kjs_window.h" + +#include "JSLocation.lut.h" + +using namespace KJS; + +namespace WebCore { + +const ClassInfo JSLocation::info = { "Location", 0, &JSLocationTable }; + +/* +@begin JSLocationTable 12 + assign WebCore::jsLocationProtoFuncAssign DontDelete|Function 1 + hash WebCore::JSLocation::Hash DontDelete + host WebCore::JSLocation::Host DontDelete + hostname WebCore::JSLocation::Hostname DontDelete + href WebCore::JSLocation::Href DontDelete + pathname WebCore::JSLocation::Pathname DontDelete + port WebCore::JSLocation::Port DontDelete + protocol WebCore::JSLocation::Protocol DontDelete + search WebCore::JSLocation::Search DontDelete + toString WebCore::jsLocationProtoFuncToString DontEnum|DontDelete|Function 0 + replace WebCore::jsLocationProtoFuncReplace DontDelete|Function 1 + reload WebCore::jsLocationProtoFuncReload DontDelete|Function 0 +@end +*/ + +JSLocation::JSLocation(JSObject* /*prototype*/, Frame* frame) + : DOMObject(jsNull()) // FIXME: this needs to take a real prototype + , m_frame(frame) +{ +} + +JSValue* JSLocation::getValueProperty(ExecState* exec, int token) const +{ + const KURL& url = m_frame->loader()->url(); + switch (token) { + case Hash: + return jsString(url.ref().isNull() ? "" : "#" + url.ref()); + case Host: { + // Note: this is the IE spec. The NS spec swaps the two, it says + // "The hostname property is the concatenation of the host and port properties, separated by a colon." + // Bleh. + UString str = url.host(); + if (url.port()) + str += ":" + String::number((int)url.port()); + return jsString(str); + } + case Hostname: + return jsString(url.host()); + case Href: + if (!url.hasPath()) + return jsString(url.prettyURL() + "/"); + return jsString(url.prettyURL()); + case Pathname: + return jsString(url.path().isEmpty() ? "/" : url.path()); + case Port: + return jsString(url.port() ? String::number((int)url.port()) : ""); + case Protocol: + return jsString(url.protocol() + ":"); + case Search: + return jsString(url.query()); + default: + ASSERT_NOT_REACHED(); + return jsUndefined(); + } +} + +bool JSLocation::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + if (customGetOwnPropertySlot(exec, propertyName, slot)) + return true; + return getStaticPropertySlot<JSLocation, JSObject>(exec, &JSLocationTable, this, propertyName, slot); +} + +bool JSLocation::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + // When accessing Location cross-domain, functions are always the native built-in ones. + // See JSDOMWindow::customGetOwnPropertySlot for additional details. + + // Our custom code is only needed to implement the Window cross-domain scheme, so if access is + // allowed, return false so the normal lookup will take place. + String message; + if (allowsAccessFromFrame(exec, m_frame, message)) + return false; + + // Check for the few functions that we allow, even when called cross-domain. + const HashEntry* entry = Lookup::findEntry(&JSLocationTable, propertyName); + if (entry && (entry->attr & Function) + && (entry->value.functionValue == jsLocationProtoFuncReplace + || entry->value.functionValue == jsLocationProtoFuncReload + || entry->value.functionValue == jsLocationProtoFuncAssign)) { + slot.setStaticEntry(this, entry, nonCachingStaticFunctionGetter); + return true; + } + // FIXME: Other implementers of the Window cross-domain scheme (Window, History) allow toString, + // but for now we have decided not to, partly because it seems silly to return "[Object Location]" in + // such cases when normally the string form of Location would be the URL. + + printErrorMessageForFrame(m_frame, message); + slot.setUndefined(this); + return true; +} + +void JSLocation::put(ExecState* exec, const Identifier& propertyName, JSValue* value) +{ + if (!m_frame) + return; + + String str = value->toString(exec); + KURL url = m_frame->loader()->url(); + bool sameDomainAccess = allowsAccessFromFrame(exec, m_frame); + + const HashEntry* entry = Lookup::findEntry(&JSLocationTable, propertyName); + + if (entry) { + // cross-domain access to the location is allowed when assigning the whole location, + // but not when assigning the individual pieces, since that might inadvertently + // disclose other parts of the original location. + if (entry->value.intValue != Href && !sameDomainAccess) + return; + + switch (entry->value.intValue) { + case Href: { + // FIXME: Why isn't this security check needed for the other properties, like Host, below? + Frame* frame = Window::retrieveActive(exec)->impl()->frame(); + if (!frame) + return; + if (!frame->loader()->shouldAllowNavigation(m_frame)) + return; + url = frame->loader()->completeURL(str); + break; + } + case Hash: + if (str.startsWith("#")) + str = str.substring(1); + if (url.ref() == str) + return; + url.setRef(str); + break; + case Host: + url.setHostAndPort(str); + break; + case Hostname: + url.setHost(str); + break; + case Pathname: + url.setPath(str); + break; + case Port: { + // FIXME: Could make this a little less ugly if String provided a toUnsignedShort function. + int port = str.toInt(); + if (port < 0 || port > 0xFFFF) + port = 0; + url.setPort(port); + break; + } + case Protocol: + url.setProtocol(str); + break; + case Search: + url.setQuery(str); + break; + default: + // Disallow changing other properties in JSLocationTable. e.g., "window.location.toString = ...". + // <http://bugs.webkit.org/show_bug.cgi?id=12720> + return; + } + } else { + if (sameDomainAccess) + JSObject::put(exec, propertyName, value); + return; + } + + Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame(); + if (!url.protocolIs("javascript") || sameDomainAccess) { + bool userGesture = activeFrame->scriptProxy()->processingUserGesture(); + m_frame->loader()->scheduleLocationChange(url.string(), activeFrame->loader()->outgoingReferrer(), false, userGesture); + } +} + +bool JSLocation::deleteProperty(ExecState* exec, const Identifier& propertyName) +{ + // Only allow deleting by frames in the same origin. + if (!allowsAccessFromFrame(exec, m_frame)) + return false; + return Base::deleteProperty(exec, propertyName); +} + +void JSLocation::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) +{ + // Only allow the location object to enumerated by frames in the same origin. + if (!allowsAccessFromFrame(exec, m_frame)) + return; + Base::getPropertyNames(exec, propertyNames); +} + +JSValue* jsLocationProtoFuncReplace(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSLocation::info)) + return throwError(exec, TypeError); + JSLocation* location = static_cast<JSLocation*>(thisObj); + Frame* frame = location->frame(); + if (!frame) + return jsUndefined(); + + Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame(); + if (activeFrame) { + if (!activeFrame->loader()->shouldAllowNavigation(frame)) + return jsUndefined(); + String str = args[0]->toString(exec); + const Window* window = Window::retrieveWindow(frame); + if (!protocolIs(str, "javascript") || (window && window->allowsAccessFrom(exec))) { + bool userGesture = activeFrame->scriptProxy()->processingUserGesture(); + frame->loader()->scheduleLocationChange(activeFrame->loader()->completeURL(str).string(), activeFrame->loader()->outgoingReferrer(), true, userGesture); + } + } + + return jsUndefined(); +} + +JSValue* jsLocationProtoFuncReload(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSLocation::info)) + return throwError(exec, TypeError); + JSLocation* location = static_cast<JSLocation*>(thisObj); + Frame* frame = location->frame(); + if (!frame) + return jsUndefined(); + + Window* window = Window::retrieveWindow(frame); + if (!window->allowsAccessFrom(exec)) + return jsUndefined(); + + if (!frame->loader()->url().protocolIs("javascript") || (window && window->allowsAccessFrom(exec))) { + bool userGesture = Window::retrieveActive(exec)->impl()->frame()->scriptProxy()->processingUserGesture(); + frame->loader()->scheduleRefresh(userGesture); + } + return jsUndefined(); +} + +JSValue* jsLocationProtoFuncAssign(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSLocation::info)) + return throwError(exec, TypeError); + JSLocation* location = static_cast<JSLocation*>(thisObj); + Frame* frame = location->frame(); + if (!frame) + return jsUndefined(); + + Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame(); + if (activeFrame) { + if (!activeFrame->loader()->shouldAllowNavigation(frame)) + return jsUndefined(); + const Window* window = Window::retrieveWindow(frame); + String dstUrl = activeFrame->loader()->completeURL(args[0]->toString(exec)).string(); + if (!protocolIs(dstUrl, "javascript") || (window && window->allowsAccessFrom(exec))) { + bool userGesture = activeFrame->scriptProxy()->processingUserGesture(); + // We want a new history item if this JS was called via a user gesture + frame->loader()->scheduleLocationChange(dstUrl, activeFrame->loader()->outgoingReferrer(), false, userGesture); + } + } + + return jsUndefined(); +} + +JSValue* jsLocationProtoFuncToString(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSLocation::info)) + return throwError(exec, TypeError); + JSLocation* location = static_cast<JSLocation*>(thisObj); + Frame* frame = location->frame(); + if (!frame) + return jsUndefined(); + if (!allowsAccessFromFrame(exec, frame)) + return jsUndefined(); + + const KURL& url = frame->loader()->url(); + if (!url.hasPath()) + return jsString(url.prettyURL() + "/"); + return jsString(url.prettyURL()); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSLocation.h b/WebCore/bindings/js/JSLocation.h new file mode 100644 index 0000000..152c8a3 --- /dev/null +++ b/WebCore/bindings/js/JSLocation.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2000 Harri Porten (porten@kde.org) + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reseved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef JSLocation_h +#define JSLocation_h + +#include "kjs_binding.h" + +namespace KJS { + class Window; +} + +namespace WebCore { + + class Frame; + + class JSLocation : public DOMObject { + typedef DOMObject Base; + + friend class KJS::Window; + public: + JSLocation(KJS::JSObject* protoype, Frame*); + + virtual bool getOwnPropertySlot(KJS::ExecState*, const KJS::Identifier&, KJS::PropertySlot&); + KJS::JSValue* getValueProperty(KJS::ExecState*, int token) const; + virtual void put(KJS::ExecState*, const KJS::Identifier&, KJS::JSValue*); + virtual bool deleteProperty(KJS::ExecState*, const KJS::Identifier&); + virtual void getPropertyNames(KJS::ExecState*, KJS::PropertyNameArray&); + + enum { + Hash, Href, Hostname, Host, + Pathname, Port, Protocol, Search, + Replace, Reload, ToString, Assign + }; + + Frame* frame() const { return m_frame; } + + virtual const KJS::ClassInfo* classInfo() const { return &info; } + static const KJS::ClassInfo info; + + private: + bool customGetOwnPropertySlot(KJS::ExecState*, const KJS::Identifier&, KJS::PropertySlot&); + + Frame* m_frame; + }; + + // Functions + KJS::JSValue* jsLocationProtoFuncAssign(KJS::ExecState*, KJS::JSObject*, const KJS::List&); + KJS::JSValue* jsLocationProtoFuncToString(KJS::ExecState*, KJS::JSObject*, const KJS::List&); + KJS::JSValue* jsLocationProtoFuncReplace(KJS::ExecState*, KJS::JSObject*, const KJS::List&); + KJS::JSValue* jsLocationProtoFuncReload(KJS::ExecState*, KJS::JSObject*, const KJS::List&); + +} // namespace WebCore + +#endif // JSLocation_h diff --git a/WebCore/bindings/js/JSNamedNodeMapCustom.cpp b/WebCore/bindings/js/JSNamedNodeMapCustom.cpp new file mode 100644 index 0000000..7cb60bf --- /dev/null +++ b/WebCore/bindings/js/JSNamedNodeMapCustom.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSNamedNodeMap.h" + +#include "NamedNodeMap.h" +#include "kjs_binding.h" +#include "kjs_dom.h" + +using namespace KJS; + +namespace WebCore { + +bool JSNamedNodeMap::canGetItemsForName(ExecState*, NamedNodeMap* impl, const Identifier& propertyName) +{ + return impl->getNamedItem(propertyName); +} + +JSValue* JSNamedNodeMap::nameGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot) +{ + JSNamedNodeMap* thisObj = static_cast<JSNamedNodeMap*>(slot.slotBase()); + return toJS(exec, thisObj->impl()->getNamedItem(propertyName)); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSNamedNodesCollection.cpp b/WebCore/bindings/js/JSNamedNodesCollection.cpp new file mode 100644 index 0000000..1fc008f --- /dev/null +++ b/WebCore/bindings/js/JSNamedNodesCollection.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSNamedNodesCollection.h" + +#include "AtomicString.h" +#include "NamedAttrMap.h" +#include "Node.h" +#include "kjs_dom.h" + +namespace WebCore { + +using namespace KJS; + +const ClassInfo JSNamedNodesCollection::info = { "Collection", 0, 0 }; + +// Such a collection is usually very short-lived, it only exists +// for constructs like document.forms.<name>[1], +// so it shouldn't be a problem that it's storing all the nodes (with the same name). (David) +JSNamedNodesCollection::JSNamedNodesCollection(KJS::JSObject* prototype, const Vector<RefPtr<Node> >& nodes) + : DOMObject(prototype) + , m_nodes(nodes) +{ +} + +JSValue* JSNamedNodesCollection::lengthGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot) +{ + JSNamedNodesCollection* thisObj = static_cast<JSNamedNodesCollection*>(slot.slotBase()); + return jsNumber(thisObj->m_nodes.size()); +} + +JSValue* JSNamedNodesCollection::indexGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot) +{ + JSNamedNodesCollection *thisObj = static_cast<JSNamedNodesCollection*>(slot.slotBase()); + return toJS(exec, thisObj->m_nodes[slot.index()].get()); +} + +bool JSNamedNodesCollection::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + if (propertyName == exec->propertyNames().length) { + slot.setCustom(this, lengthGetter); + return true; + } + + bool ok; + unsigned index = propertyName.toUInt32(&ok); + if (ok && index < m_nodes.size()) { + slot.setCustomIndex(this, index, indexGetter); + return true; + } + + // For IE compatibility, we need to be able to look up elements in a + // document.formName.name result by id as well as be index. + + AtomicString atomicPropertyName = propertyName; + for (unsigned i = 0; i < m_nodes.size(); i++) { + Node* node = m_nodes[i].get(); + if (node->hasAttributes() && node->attributes()->id() == atomicPropertyName) { + slot.setCustomIndex(this, i, indexGetter); + return true; + } + } + + return DOMObject::getOwnPropertySlot(exec, propertyName, slot); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSNamedNodesCollection.h b/WebCore/bindings/js/JSNamedNodesCollection.h new file mode 100644 index 0000000..4b89c80 --- /dev/null +++ b/WebCore/bindings/js/JSNamedNodesCollection.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSNamedNodesCollection_h +#define JSNamedNodesCollection_h + +#include "kjs_binding.h" +#include <wtf/Vector.h> + +namespace WebCore { + + class Node; + + // Internal class, used for the collection return by e.g. document.forms.myinput + // when multiple nodes have the same name. + class JSNamedNodesCollection : public DOMObject { + public: + JSNamedNodesCollection(KJS::JSObject* prototype, const Vector<RefPtr<Node> >&); + + virtual bool getOwnPropertySlot(KJS::ExecState*, const KJS::Identifier&, KJS::PropertySlot&); + + virtual const KJS::ClassInfo* classInfo() const { return &info; } + static const KJS::ClassInfo info; + + private: + static KJS::JSValue* lengthGetter(KJS::ExecState*, KJS::JSObject*, const KJS::Identifier&, const KJS::PropertySlot&); + static KJS::JSValue* indexGetter(KJS::ExecState*, KJS::JSObject*, const KJS::Identifier&, const KJS::PropertySlot&); + + Vector<RefPtr<Node> > m_nodes; + }; + +} // namespace WebCore + +#endif // JSNamedNodesCollection_h diff --git a/WebCore/bindings/js/JSNodeCustom.cpp b/WebCore/bindings/js/JSNodeCustom.cpp new file mode 100644 index 0000000..20fdad2 --- /dev/null +++ b/WebCore/bindings/js/JSNodeCustom.cpp @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSNode.h" + +#include "Attr.h" +#include "CDATASection.h" +#include "Comment.h" +#include "Document.h" +#include "DocumentFragment.h" +#include "DocumentType.h" +#include "Entity.h" +#include "EntityReference.h" +#include "HTMLElement.h" +#include "JSAttr.h" +#include "JSCDATASection.h" +#include "JSComment.h" +#include "JSDocument.h" +#include "JSDocumentFragment.h" +#include "JSDocumentType.h" +#include "JSEntity.h" +#include "JSEntityReference.h" +#include "JSHTMLElement.h" +#include "JSHTMLElementWrapperFactory.h" +#include "JSNotation.h" +#include "JSProcessingInstruction.h" +#include "JSText.h" +#include "Node.h" +#include "Notation.h" +#include "ProcessingInstruction.h" +#include "Text.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +#if ENABLE(SVG) +#include "JSSVGElementWrapperFactory.h" +#include "SVGElement.h" +#endif + +using namespace KJS; + +namespace WebCore { + +typedef int ExpectionCode; + +JSValue* JSNode::insertBefore(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + bool ok = impl()->insertBefore(toNode(args[0]), toNode(args[1]), ec); + setDOMException(exec, ec); + if (ok) + return args[0]; + return jsNull(); +} + +JSValue* JSNode::replaceChild(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + bool ok = impl()->replaceChild(toNode(args[0]), toNode(args[1]), ec); + setDOMException(exec, ec); + if (ok) + return args[1]; + return jsNull(); +} + +JSValue* JSNode::removeChild(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + bool ok = impl()->removeChild(toNode(args[0]), ec); + setDOMException(exec, ec); + if (ok) + return args[0]; + return jsNull(); +} + +JSValue* JSNode::appendChild(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + bool ok = impl()->appendChild(toNode(args[0]), ec); + setDOMException(exec, ec); + if (ok) + return args[0]; + return jsNull(); +} + +void JSNode::mark() +{ + ASSERT(!marked()); + + Node* node = m_impl.get(); + + // Nodes in the document are kept alive by ScriptInterpreter::mark, + // so we have no special responsibilities and can just call the base class here. + if (node->inDocument()) { + DOMObject::mark(); + return; + } + + // This is a node outside the document, so find the root of the tree it is in, + // and start marking from there. + Node* root = node; + for (Node* current = m_impl.get(); current; current = current->parentNode()) + root = current; + + // If we're already marking this tree, then we can simply mark this wrapper + // by calling the base class; our caller is iterating the tree. + if (root->m_inSubtreeMark) { + DOMObject::mark(); + return; + } + + // Mark the whole tree; use the global set of roots to avoid reentering. + root->m_inSubtreeMark = true; + for (Node* nodeToMark = root; nodeToMark; nodeToMark = nodeToMark->traverseNextNode()) { + JSNode* wrapper = ScriptInterpreter::getDOMNodeForDocument(m_impl->document(), nodeToMark); + if (wrapper) { + if (!wrapper->marked()) + wrapper->mark(); + } else if (nodeToMark == node) { + // This is the case where the map from the document to wrappers has + // been cleared out, but a wrapper is being marked. For now, we'll + // let the rest of the tree of wrappers get collected, because we have + // no good way of finding them. Later we should test behavior of other + // browsers and see if we need to preserve other wrappers in this case. + if (!marked()) + mark(); + } + } + root->m_inSubtreeMark = false; + + // Double check that we actually ended up marked. This assert caught problems in the past. + ASSERT(marked()); +} + +JSValue* toJS(ExecState* exec, PassRefPtr<Node> n) +{ + Node* node = n.get(); + if (!node) + return jsNull(); + + Document* doc = node->document(); + JSNode* ret = ScriptInterpreter::getDOMNodeForDocument(doc, node); + if (ret) + return ret; + + switch (node->nodeType()) { + case Node::ELEMENT_NODE: + if (node->isHTMLElement()) + ret = createJSHTMLWrapper(exec, static_pointer_cast<HTMLElement>(n)); +#if ENABLE(SVG) + else if (node->isSVGElement()) + ret = createJSSVGWrapper(exec, static_pointer_cast<SVGElement>(n)); +#endif + else + ret = new JSElement(JSElementPrototype::self(exec), static_cast<Element*>(node)); + break; + case Node::ATTRIBUTE_NODE: + ret = new JSAttr(JSAttrPrototype::self(exec), static_cast<Attr*>(node)); + break; + case Node::TEXT_NODE: + ret = new JSText(JSTextPrototype::self(exec), static_cast<Text*>(node)); + break; + case Node::CDATA_SECTION_NODE: + ret = new JSCDATASection(JSCDATASectionPrototype::self(exec), static_cast<CDATASection*>(node)); + break; + case Node::ENTITY_NODE: + ret = new JSEntity(JSEntityPrototype::self(exec), static_cast<Entity*>(node)); + break; + case Node::PROCESSING_INSTRUCTION_NODE: + ret = new JSProcessingInstruction(JSProcessingInstructionPrototype::self(exec), static_cast<ProcessingInstruction*>(node)); + break; + case Node::COMMENT_NODE: + ret = new JSComment(JSCommentPrototype::self(exec), static_cast<Comment*>(node)); + break; + case Node::DOCUMENT_NODE: + // we don't want to cache the document itself in the per-document dictionary + return toJS(exec, static_cast<Document*>(node)); + case Node::DOCUMENT_TYPE_NODE: + ret = new JSDocumentType(JSDocumentTypePrototype::self(exec), static_cast<DocumentType*>(node)); + break; + case Node::NOTATION_NODE: + ret = new JSNotation(JSNotationPrototype::self(exec), static_cast<Notation*>(node)); + break; + case Node::DOCUMENT_FRAGMENT_NODE: + ret = new JSDocumentFragment(JSDocumentFragmentPrototype::self(exec), static_cast<DocumentFragment*>(node)); + break; + case Node::ENTITY_REFERENCE_NODE: + ret = new JSEntityReference(JSEntityReferencePrototype::self(exec), static_cast<EntityReference*>(node)); + break; + default: + ret = new JSNode(JSNodePrototype::self(exec), node); + } + + ScriptInterpreter::putDOMNodeForDocument(doc, node, ret); + + return ret; +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSNodeFilterCondition.cpp b/WebCore/bindings/js/JSNodeFilterCondition.cpp new file mode 100644 index 0000000..17884f9 --- /dev/null +++ b/WebCore/bindings/js/JSNodeFilterCondition.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "JSNodeFilterCondition.h" + +#include "Document.h" +#include "Frame.h" +#include "JSNode.h" +#include "JSNodeFilter.h" +#include "NodeFilter.h" +#include "kjs_proxy.h" + +namespace WebCore { + +using namespace KJS; + +// FIXME: Add takeException as a member of ExecState? +static JSValue* takeException(ExecState* exec) +{ + JSValue* exception = exec->exception(); + exec->clearException(); + return exception; +} + +JSNodeFilterCondition::JSNodeFilterCondition(JSObject* filter) + : m_filter(filter) +{ +} + +void JSNodeFilterCondition::mark() +{ + m_filter->mark(); +} + +short JSNodeFilterCondition::acceptNode(Node* filterNode, JSValue*& exception) const +{ + // FIXME: It makes no sense for this to depend on the document being in a frame! + Frame* frame = filterNode->document()->frame(); + if (!frame) + return NodeFilter::FILTER_REJECT; + + JSLock lock; + + if (!m_filter->implementsCall()) + return NodeFilter::FILTER_REJECT; + + ExecState* exec = frame->scriptProxy()->globalObject()->globalExec(); + List args; + args.append(toJS(exec, filterNode)); + if (exec->hadException()) { + exception = takeException(exec); + return NodeFilter::FILTER_REJECT; + } + JSValue* result = m_filter->call(exec, m_filter, args); + if (exec->hadException()) { + exception = takeException(exec); + return NodeFilter::FILTER_REJECT; + } + int intResult = result->toInt32(exec); + if (exec->hadException()) { + exception = takeException(exec); + return NodeFilter::FILTER_REJECT; + } + return intResult; +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSNodeFilterCondition.h b/WebCore/bindings/js/JSNodeFilterCondition.h new file mode 100644 index 0000000..65519e9 --- /dev/null +++ b/WebCore/bindings/js/JSNodeFilterCondition.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef JSNodeFilterCondition_h +#define JSNodeFilterCondition_h + +#include "NodeFilterCondition.h" + +namespace KJS { + class JSObject; +} + +namespace WebCore { + + class Node; + + class JSNodeFilterCondition : public NodeFilterCondition { + public: + JSNodeFilterCondition(KJS::JSObject* filter); + virtual short acceptNode(Node*, KJS::JSValue*& exception) const; + virtual void mark(); + + protected: + KJS::JSObject* m_filter; + }; + +} // namespace WebCore + +#endif // JSNodeFilterCondition_h diff --git a/WebCore/bindings/js/JSNodeFilterCustom.cpp b/WebCore/bindings/js/JSNodeFilterCustom.cpp new file mode 100644 index 0000000..413abf9 --- /dev/null +++ b/WebCore/bindings/js/JSNodeFilterCustom.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSNodeFilter.h" + +#include "JSNodeFilterCondition.h" +#include "NodeFilter.h" +#include "kjs_binding.h" +#include "kjs_dom.h" + +using namespace KJS; + +namespace WebCore { + +void JSNodeFilter::mark() +{ + impl()->mark(); + DOMObject::mark(); +} + +JSValue* JSNodeFilter::acceptNode(ExecState* exec, const List& args) +{ + JSValue* exception = 0; + short result = impl()->acceptNode(toNode(args[0]), exception); + if (exception) + exec->setException(exception); + return jsNumber(result); +} + +NodeFilter* toNodeFilter(KJS::JSValue* val) +{ + if (!val || !val->isObject()) + return 0; + + if (val->isObject(&JSNodeFilter::info)) + return static_cast<JSNodeFilter*>(val)->impl(); + + KJS::JSObject* o = static_cast<KJS::JSObject*>(val); + if (o->implementsCall()) + return new NodeFilter(new JSNodeFilterCondition(o)); + + return 0; +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSNodeIteratorCustom.cpp b/WebCore/bindings/js/JSNodeIteratorCustom.cpp new file mode 100644 index 0000000..937efa0 --- /dev/null +++ b/WebCore/bindings/js/JSNodeIteratorCustom.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "JSNodeIterator.h" + +#include "JSNode.h" +#include "Node.h" +#include "NodeFilter.h" +#include "NodeIterator.h" + +using namespace KJS; + +namespace WebCore { + +void JSNodeIterator::mark() +{ + if (NodeFilter* filter = m_impl->filter()) + filter->mark(); + + DOMObject::mark(); +} + +JSValue* JSNodeIterator::nextNode(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + JSValue* exception = 0; + Node* node = impl()->nextNode(ec, exception); + if (ec) { + setDOMException(exec, ec); + return jsUndefined(); + } + if (exception) { + exec->setException(exception); + return jsUndefined(); + } + return toJS(exec, node); +} + +JSValue* JSNodeIterator::previousNode(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + JSValue* exception = 0; + Node* node = impl()->previousNode(ec, exception); + if (ec) { + setDOMException(exec, ec); + return jsUndefined(); + } + if (exception) { + exec->setException(exception); + return jsUndefined(); + } + return toJS(exec, node); +} + +} diff --git a/WebCore/bindings/js/JSNodeListCustom.cpp b/WebCore/bindings/js/JSNodeListCustom.cpp new file mode 100644 index 0000000..e484cb4 --- /dev/null +++ b/WebCore/bindings/js/JSNodeListCustom.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSNodeList.h" + +#include "AtomicString.h" +#include "JSNode.h" +#include "Node.h" +#include "NodeList.h" + +namespace WebCore { + +// Need to support both get and call, so that list[0] and list(0) work. +KJS::JSValue* JSNodeList::callAsFunction(KJS::ExecState* exec, KJS::JSObject* thisObj, const KJS::List& args) +{ + // Do not use thisObj here. See JSHTMLCollection. + KJS::UString s = args[0]->toString(exec); + bool ok; + unsigned u = s.toUInt32(&ok); + if (ok) + return toJS(exec, impl()->item(u)); + + return KJS::jsUndefined(); +} + +bool JSNodeList::implementsCall() const +{ + return true; +} + +bool JSNodeList::canGetItemsForName(KJS::ExecState*, NodeList* impl, const KJS::Identifier& propertyName) +{ + return impl->itemWithName(propertyName); +} + +KJS::JSValue* JSNodeList::nameGetter(KJS::ExecState* exec, KJS::JSObject* originalObject, const KJS::Identifier& propertyName, const KJS::PropertySlot& slot) +{ + JSNodeList* thisObj = static_cast<JSNodeList*>(slot.slotBase()); + return toJS(exec, thisObj->impl()->itemWithName(propertyName)); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSSQLResultSetRowListCustom.cpp b/WebCore/bindings/js/JSSQLResultSetRowListCustom.cpp new file mode 100644 index 0000000..62dcd5d --- /dev/null +++ b/WebCore/bindings/js/JSSQLResultSetRowListCustom.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSSQLResultSetRowList.h" + +#include "ExceptionCode.h" +#include "SQLValue.h" +#include "SQLResultSetRowList.h" + +using namespace KJS; + +namespace WebCore { + +JSValue* JSSQLResultSetRowList::item(ExecState* exec, const List& args) +{ + bool indexOk; + int index = args[0]->toInt32(exec, indexOk); + if (!indexOk) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + if (index < 0 || (unsigned)index >= m_impl->length()) { + setDOMException(exec, INDEX_SIZE_ERR); + return jsUndefined(); + } + + JSObject* object = new JSObject(exec->lexicalGlobalObject()->objectPrototype()); + + unsigned numColumns = m_impl->columnNames().size(); + unsigned valuesIndex = index * numColumns; + for (unsigned i = 0; i < numColumns; i++) { + const SQLValue& value = m_impl->values()[valuesIndex + i]; + JSValue* jsValue = 0; + + switch (value.type()) { + case SQLValue::StringValue: + jsValue = jsString(value.string()); + break; + case SQLValue::NullValue: + jsValue = jsNull(); + break; + case SQLValue::NumberValue: + jsValue = jsNumber(value.number()); + break; + default: + ASSERT_NOT_REACHED(); + } + + object->putDirect(m_impl->columnNames()[i], jsValue, DontDelete | ReadOnly); + } + + return object; +} + +} diff --git a/WebCore/bindings/js/JSSQLTransactionCustom.cpp b/WebCore/bindings/js/JSSQLTransactionCustom.cpp new file mode 100644 index 0000000..1dca46d --- /dev/null +++ b/WebCore/bindings/js/JSSQLTransactionCustom.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSSQLTransaction.h" + +#include "DOMWindow.h" +#include "ExceptionCode.h" +#include "JSCustomSQLStatementCallback.h" +#include "JSCustomSQLStatementErrorCallback.h" +#include "SQLTransaction.h" +#include "kjs_window.h" + +using namespace KJS; + +namespace WebCore { + +JSValue* JSSQLTransaction::executeSql(ExecState* exec, const List& args) +{ + String sqlStatement = args[0]->toString(exec); + if (exec->hadException()) + return jsUndefined(); + + // Now assemble the list of SQL arguments + Vector<SQLValue> sqlValues; + if (!args[1]->isUndefinedOrNull()) { + JSObject* object = args[1]->getObject(); + if (!object) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + JSValue* lengthValue = object->get(exec, exec->propertyNames().length); + if (exec->hadException()) + return jsUndefined(); + unsigned length = lengthValue->toUInt32(exec); + if (exec->hadException()) + return jsUndefined(); + + for (unsigned i = 0 ; i < length; ++i) { + JSValue* value = object->get(exec, i); + if (exec->hadException()) + return jsUndefined(); + + if (value->isNull()) + sqlValues.append(SQLValue()); + else if (value->isNumber()) + sqlValues.append(value->getNumber()); + else { + // Convert the argument to a string and append it + sqlValues.append(value->toString(exec)); + if (exec->hadException()) + return jsUndefined(); + } + } + } + + RefPtr<SQLStatementCallback> callback; + if (!args[2]->isUndefinedOrNull()) { + JSObject* object = args[2]->getObject(); + if (!object) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + if (Frame* frame = Window::retrieveActive(exec)->impl()->frame()) + callback = new JSCustomSQLStatementCallback(object, frame); + } + + RefPtr<SQLStatementErrorCallback> errorCallback; + if (!args[3]->isUndefinedOrNull()) { + JSObject* object = args[3]->getObject(); + if (!object) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + if (Frame* frame = Window::retrieveActive(exec)->impl()->frame()) + errorCallback = new JSCustomSQLStatementErrorCallback(object, frame); + } + + ExceptionCode ec = 0; + m_impl->executeSQL(sqlStatement, sqlValues, callback.release(), errorCallback.release(), ec); + setDOMException(exec, ec); + + return jsUndefined(); +} + +} diff --git a/WebCore/bindings/js/JSSVGElementWrapperFactory.cpp b/WebCore/bindings/js/JSSVGElementWrapperFactory.cpp new file mode 100644 index 0000000..29ead3d --- /dev/null +++ b/WebCore/bindings/js/JSSVGElementWrapperFactory.cpp @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#if ENABLE(SVG) + +#include "JSSVGElementWrapperFactory.h" + +#include "JSSVGAElement.h" +#include "JSSVGAnimateColorElement.h" +#include "JSSVGAnimateElement.h" +#include "JSSVGAnimateTransformElement.h" +#include "JSSVGCircleElement.h" +#include "JSSVGClipPathElement.h" +#include "JSSVGCursorElement.h" +#include "JSSVGDefsElement.h" +#include "JSSVGDefinitionSrcElement.h" +#include "JSSVGDescElement.h" +#include "JSSVGEllipseElement.h" +#include "JSSVGFEBlendElement.h" +#include "JSSVGFEColorMatrixElement.h" +#include "JSSVGFEComponentTransferElement.h" +#include "JSSVGFECompositeElement.h" +#include "JSSVGFEDiffuseLightingElement.h" +#include "JSSVGFEDisplacementMapElement.h" +#include "JSSVGFEDistantLightElement.h" +#include "JSSVGFEFloodElement.h" +#include "JSSVGFEFuncAElement.h" +#include "JSSVGFEFuncBElement.h" +#include "JSSVGFEFuncGElement.h" +#include "JSSVGFEFuncRElement.h" +#include "JSSVGFEGaussianBlurElement.h" +#include "JSSVGFEImageElement.h" +#include "JSSVGFEMergeElement.h" +#include "JSSVGFEMergeNodeElement.h" +#include "JSSVGFEOffsetElement.h" +#include "JSSVGFEPointLightElement.h" +#include "JSSVGFESpecularLightingElement.h" +#include "JSSVGFESpotLightElement.h" +#include "JSSVGFETileElement.h" +#include "JSSVGFETurbulenceElement.h" +#include "JSSVGFilterElement.h" +#include "JSSVGForeignObjectElement.h" +#include "JSSVGFontElement.h" +#include "JSSVGFontFaceElement.h" +#include "JSSVGFontFaceFormatElement.h" +#include "JSSVGFontFaceNameElement.h" +#include "JSSVGFontFaceSrcElement.h" +#include "JSSVGFontFaceUriElement.h" +#include "JSSVGGElement.h" +#include "JSSVGGlyphElement.h" +#include "JSSVGImageElement.h" +#include "JSSVGLinearGradientElement.h" +#include "JSSVGLineElement.h" +#include "JSSVGMarkerElement.h" +#include "JSSVGMaskElement.h" +#include "JSSVGMetadataElement.h" +#include "JSSVGMissingGlyphElement.h" +#include "JSSVGPathElement.h" +#include "JSSVGPatternElement.h" +#include "JSSVGPolygonElement.h" +#include "JSSVGPolylineElement.h" +#include "JSSVGRadialGradientElement.h" +#include "JSSVGRectElement.h" +#include "JSSVGScriptElement.h" +#include "JSSVGSetElement.h" +#include "JSSVGStopElement.h" +#include "JSSVGStyleElement.h" +#include "JSSVGSVGElement.h" +#include "JSSVGSwitchElement.h" +#include "JSSVGSymbolElement.h" +#include "JSSVGTextElement.h" +#include "JSSVGTextPathElement.h" +#include "JSSVGTitleElement.h" +#include "JSSVGTRefElement.h" +#include "JSSVGTSpanElement.h" +#include "JSSVGUseElement.h" +#include "JSSVGViewElement.h" + +#include "SVGNames.h" + +#include "SVGAElement.h" +#include "SVGAnimateColorElement.h" +#include "SVGAnimateElement.h" +#include "SVGAnimateTransformElement.h" +#include "SVGCircleElement.h" +#include "SVGClipPathElement.h" +#include "SVGCursorElement.h" +#include "SVGDefsElement.h" +#include "SVGDefinitionSrcElement.h" +#include "SVGDescElement.h" +#include "SVGEllipseElement.h" +#include "SVGFEBlendElement.h" +#include "SVGFEColorMatrixElement.h" +#include "SVGFEComponentTransferElement.h" +#include "SVGFECompositeElement.h" +#include "SVGFEDiffuseLightingElement.h" +#include "SVGFEDisplacementMapElement.h" +#include "SVGFEDistantLightElement.h" +#include "SVGFEFloodElement.h" +#include "SVGFEFuncAElement.h" +#include "SVGFEFuncBElement.h" +#include "SVGFEFuncGElement.h" +#include "SVGFEFuncRElement.h" +#include "SVGFEGaussianBlurElement.h" +#include "SVGFEImageElement.h" +#include "SVGFEMergeElement.h" +#include "SVGFEMergeNodeElement.h" +#include "SVGFEOffsetElement.h" +#include "SVGFEPointLightElement.h" +#include "SVGFESpecularLightingElement.h" +#include "SVGFESpotLightElement.h" +#include "SVGFETileElement.h" +#include "SVGFETurbulenceElement.h" +#include "SVGFilterElement.h" +#include "SVGForeignObjectElement.h" +#include "SVGFontElement.h" +#include "SVGFontFaceElement.h" +#include "SVGFontFaceFormatElement.h" +#include "SVGFontFaceNameElement.h" +#include "SVGFontFaceSrcElement.h" +#include "SVGFontFaceUriElement.h" +#include "SVGGElement.h" +#include "SVGGlyphElement.h" +#include "SVGImageElement.h" +#include "SVGLinearGradientElement.h" +#include "SVGLineElement.h" +#include "SVGMarkerElement.h" +#include "SVGMaskElement.h" +#include "SVGMetadataElement.h" +#include "SVGMissingGlyphElement.h" +#include "SVGPathElement.h" +#include "SVGPatternElement.h" +#include "SVGPolygonElement.h" +#include "SVGPolylineElement.h" +#include "SVGRadialGradientElement.h" +#include "SVGRectElement.h" +#include "SVGScriptElement.h" +#include "SVGSetElement.h" +#include "SVGStopElement.h" +#include "SVGStyleElement.h" +#include "SVGSVGElement.h" +#include "SVGSwitchElement.h" +#include "SVGSymbolElement.h" +#include "SVGTextElement.h" +#include "SVGTextPathElement.h" +#include "SVGTitleElement.h" +#include "SVGTRefElement.h" +#include "SVGTSpanElement.h" +#include "SVGUseElement.h" +#include "SVGViewElement.h" + +using namespace KJS; + +// FIXME: Eventually this file should be autogenerated, just like SVGNames, SVGElementFactory, etc. + +namespace WebCore { + +using namespace SVGNames; + +typedef JSNode* (*CreateSVGElementWrapperFunction)(ExecState*, PassRefPtr<SVGElement>); + +#if ENABLE(SVG_ANIMATION) +#define FOR_EACH_ANIMATION_TAG(macro) \ + macro(animateColor, AnimateColor) \ + macro(animate, Animate) \ + macro(animateTransform, AnimateTransform) \ + // end of macro + +#else +#define FOR_EACH_ANIMATION_TAG(macro) +#endif + + +#if ENABLE(SVG_FONTS) +#define FOR_EACH_FONT_TAG(macro) \ + macro(definition_src, DefinitionSrc) \ + macro(font, Font) \ + macro(font_face, FontFace) \ + macro(font_face_format, FontFaceFormat) \ + macro(font_face_name, FontFaceName) \ + macro(font_face_src, FontFaceSrc) \ + macro(font_face_uri, FontFaceUri) \ + macro(glyph, Glyph) \ + macro(missing_glyph, MissingGlyph) + // end of macro + +#else +#define FOR_EACH_FONT_TAG(macro) +#endif + +#if ENABLE(SVG_FILTERS) +#define FOR_EACH_FILTER_TAG(macro) \ + macro(feBlend, FEBlend) \ + macro(feColorMatrix, FEColorMatrix) \ + macro(feComponentTransfer, FEComponentTransfer) \ + macro(feComposite, FEComposite) \ + macro(feDiffuseLighting, FEDiffuseLighting) \ + macro(feDisplacementMap, FEDisplacementMap) \ + macro(feDistantLight, FEDistantLight) \ + macro(feFlood, FEFlood) \ + macro(feFuncA, FEFuncA) \ + macro(feFuncB, FEFuncB) \ + macro(feFuncG, FEFuncG) \ + macro(feFuncR, FEFuncR) \ + macro(feGaussianBlur, FEGaussianBlur) \ + macro(feImage, FEImage) \ + macro(feMerge, FEMerge) \ + macro(feMergeNode, FEMergeNode) \ + macro(feOffset, FEOffset) \ + macro(fePointLight, FEPointLight) \ + macro(feSpecularLighting, FESpecularLighting) \ + macro(feSpotLight, FESpotLight) \ + macro(feTile, FETile) \ + macro(feTurbulence, FETurbulence) \ + macro(filter, Filter) \ + // end of macro +#else +#define FOR_EACH_FILTER_TAG(macro) +#endif + +#if ENABLE(SVG_FOREIGN_OBJECT) +#define FOR_EACH_FOREIGN_OBJECT_TAG(macro) \ + macro(foreignObject, ForeignObject) \ + // end of macro +#else +#define FOR_EACH_FOREIGN_OBJECT_TAG(macro) +#endif + +#define FOR_EACH_TAG(macro) \ + macro(a, A) \ + macro(circle, Circle) \ + macro(clipPath, ClipPath) \ + macro(cursor, Cursor) \ + macro(defs, Defs) \ + macro(desc, Desc) \ + macro(ellipse, Ellipse) \ + macro(g, G) \ + macro(image, Image) \ + macro(linearGradient, LinearGradient) \ + macro(line, Line) \ + macro(marker, Marker) \ + macro(mask, Mask) \ + macro(metadata, Metadata) \ + macro(path, Path) \ + macro(pattern, Pattern) \ + macro(polyline, Polyline) \ + macro(polygon, Polygon) \ + macro(radialGradient, RadialGradient) \ + macro(rect, Rect) \ + macro(script, Script) \ + macro(set, Set) \ + macro(stop, Stop) \ + macro(style, Style) \ + macro(svg, SVG) \ + macro(switch, Switch) \ + macro(symbol, Symbol) \ + macro(text, Text) \ + macro(textPath, TextPath) \ + macro(title, Title) \ + macro(tref, TRef) \ + macro(tspan, TSpan) \ + macro(use, Use) \ + macro(view, View) \ + // end of macro + +#define CREATE_WRAPPER_FUNCTION(tag, name) \ +static JSNode* create##name##Wrapper(ExecState* exec, PassRefPtr<SVGElement> element) \ +{ \ + return new JSSVG##name##Element(JSSVG##name##ElementPrototype::self(exec), static_cast<SVG##name##Element*>(element.get())); \ +} +FOR_EACH_TAG(CREATE_WRAPPER_FUNCTION) +FOR_EACH_ANIMATION_TAG(CREATE_WRAPPER_FUNCTION) +FOR_EACH_FONT_TAG(CREATE_WRAPPER_FUNCTION) +FOR_EACH_FILTER_TAG(CREATE_WRAPPER_FUNCTION) +FOR_EACH_FOREIGN_OBJECT_TAG(CREATE_WRAPPER_FUNCTION) + +#undef CREATE_WRAPPER_FUNCTION + +JSNode* createJSSVGWrapper(ExecState* exec, PassRefPtr<SVGElement> element) +{ + static HashMap<WebCore::AtomicStringImpl*, CreateSVGElementWrapperFunction> map; + if (map.isEmpty()) { +#define ADD_TO_HASH_MAP(tag, name) map.set(tag##Tag.localName().impl(), create##name##Wrapper); +FOR_EACH_TAG(ADD_TO_HASH_MAP) +FOR_EACH_ANIMATION_TAG(ADD_TO_HASH_MAP) +FOR_EACH_FONT_TAG(ADD_TO_HASH_MAP) +FOR_EACH_FILTER_TAG(ADD_TO_HASH_MAP) +FOR_EACH_FOREIGN_OBJECT_TAG(ADD_TO_HASH_MAP) +#undef ADD_TO_HASH_MAP + } + CreateSVGElementWrapperFunction createWrapperFunction = map.get(element->localName().impl()); + if (createWrapperFunction) + return createWrapperFunction(exec, element); + return new JSSVGElement(JSSVGElementPrototype::self(exec), element.get()); +} + +} + +#endif // ENABLE(SVG) diff --git a/WebCore/bindings/js/JSSVGElementWrapperFactory.h b/WebCore/bindings/js/JSSVGElementWrapperFactory.h new file mode 100644 index 0000000..3083fec --- /dev/null +++ b/WebCore/bindings/js/JSSVGElementWrapperFactory.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef JSSVGElementWrapperFactory_h +#define JSSVGElementWrapperFactory_h + +#if ENABLE(SVG) + +#include <wtf/Forward.h> + +namespace KJS { + class ExecState; +} + +namespace WebCore { + + class JSNode; + class SVGElement; + + JSNode* createJSSVGWrapper(KJS::ExecState*, PassRefPtr<SVGElement>); + +} + +#endif // ENABLE(SVG) + +#endif // JSSVGElementWrapperFactory_h diff --git a/WebCore/bindings/js/JSSVGLazyEventListener.cpp b/WebCore/bindings/js/JSSVGLazyEventListener.cpp new file mode 100644 index 0000000..87d0cc6 --- /dev/null +++ b/WebCore/bindings/js/JSSVGLazyEventListener.cpp @@ -0,0 +1,46 @@ +/* + Copyright (C) 2006 Apple Computer, Inc. + + This file is part of the WebKit project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#if ENABLE(SVG) + +#include "JSSVGLazyEventListener.h" + +using namespace KJS; + +namespace WebCore { + +JSSVGLazyEventListener::JSSVGLazyEventListener(const String& functionName, const String& code, KJS::Window* win, Node* node, int lineno) + : JSLazyEventListener(functionName, code, win, node, lineno) +{ +} + +JSValue *JSSVGLazyEventListener::eventParameterName() const +{ + static ProtectedPtr<JSValue> eventString = jsString("evt"); + return eventString.get(); +} + +} + +#endif // ENABLE(SVG) + +// vim:ts=4:noet diff --git a/WebCore/bindings/js/JSSVGLazyEventListener.h b/WebCore/bindings/js/JSSVGLazyEventListener.h new file mode 100644 index 0000000..8247bdb --- /dev/null +++ b/WebCore/bindings/js/JSSVGLazyEventListener.h @@ -0,0 +1,42 @@ +/* + Copyright (C) 2006 Apple Computer, Inc. + + This file is part of the WebKit project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef JSSVGLazyEventListener_h +#define JSSVGLazyEventListener_h +#if ENABLE(SVG) + +#include "kjs_events.h" + +namespace WebCore { + + class JSSVGLazyEventListener : public JSLazyEventListener { + public: + JSSVGLazyEventListener(const String& functionName, const String& code, KJS::Window*, Node*, int lineno = 0); + private: + virtual KJS::JSValue* eventParameterName() const; + }; + +} + +#endif // ENABLE(SVG) +#endif + +// vim:ts=4:noet diff --git a/WebCore/bindings/js/JSSVGMatrixCustom.cpp b/WebCore/bindings/js/JSSVGMatrixCustom.cpp new file mode 100644 index 0000000..99da930 --- /dev/null +++ b/WebCore/bindings/js/JSSVGMatrixCustom.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#if ENABLE(SVG) + +#include "JSSVGMatrix.h" + +#include "AffineTransform.h" +#include "SVGException.h" + +using namespace KJS; + +namespace WebCore { + +JSValue* JSSVGMatrix::multiply(ExecState* exec, const List& args) +{ + AffineTransform imp(*impl()); + + AffineTransform secondMatrix = toSVGMatrix(args[0]); + return toJS(exec, new JSSVGPODTypeWrapperCreatorReadOnly<AffineTransform>(imp.multiply(secondMatrix)), m_context.get()); +} + +JSValue* JSSVGMatrix::inverse(ExecState* exec, const List&) +{ + AffineTransform imp(*impl()); + KJS::JSValue* result = toJS(exec, new JSSVGPODTypeWrapperCreatorReadOnly<AffineTransform>(imp.inverse()), m_context.get()); + + if (!imp.isInvertible()) + setDOMException(exec, SVGException::SVG_MATRIX_NOT_INVERTABLE); + + return result; +} + +JSValue* JSSVGMatrix::translate(ExecState* exec, const List& args) +{ + AffineTransform imp(*impl()); + + float x = args[0]->toFloat(exec); + float y = args[1]->toFloat(exec); + + return toJS(exec, new JSSVGPODTypeWrapperCreatorReadOnly<AffineTransform>(imp.translate(x, y)), m_context.get()); +} + +JSValue* JSSVGMatrix::scale(ExecState* exec, const List& args) +{ + AffineTransform imp(*impl()); + + float scaleFactor = args[0]->toFloat(exec); + return toJS(exec, new JSSVGPODTypeWrapperCreatorReadOnly<AffineTransform>(imp.scale(scaleFactor)), m_context.get()); +} + +JSValue* JSSVGMatrix::scaleNonUniform(ExecState* exec, const List& args) +{ + AffineTransform imp(*impl()); + + float scaleFactorX = args[0]->toFloat(exec); + float scaleFactorY = args[1]->toFloat(exec); + + return toJS(exec, new JSSVGPODTypeWrapperCreatorReadOnly<AffineTransform>(imp.scaleNonUniform(scaleFactorX, scaleFactorY)), m_context.get()); +} + +JSValue* JSSVGMatrix::rotate(ExecState* exec, const List& args) +{ + AffineTransform imp(*impl()); + + float angle = args[0]->toFloat(exec); + return toJS(exec, new JSSVGPODTypeWrapperCreatorReadOnly<AffineTransform>(imp.rotate(angle)), m_context.get()); +} + +JSValue* JSSVGMatrix::rotateFromVector(ExecState* exec, const List& args) +{ + AffineTransform imp(*impl()); + + float x = args[0]->toFloat(exec); + float y = args[1]->toFloat(exec); + + KJS::JSValue* result = toJS(exec, new JSSVGPODTypeWrapperCreatorReadOnly<AffineTransform>(imp.rotateFromVector(x, y)), m_context.get()); + + if (x == 0.0 || y == 0.0) + setDOMException(exec, SVGException::SVG_INVALID_VALUE_ERR); + + return result; +} + +JSValue* JSSVGMatrix::flipX(ExecState* exec, const List&) +{ + AffineTransform imp(*impl()); + return toJS(exec, new JSSVGPODTypeWrapperCreatorReadOnly<AffineTransform>(imp.flipX()), m_context.get()); +} + +JSValue* JSSVGMatrix::flipY(ExecState* exec, const List&) +{ + AffineTransform imp(*impl()); + return toJS(exec, new JSSVGPODTypeWrapperCreatorReadOnly<AffineTransform>(imp.flipY()), m_context.get()); +} + +JSValue* JSSVGMatrix::skewX(ExecState* exec, const List& args) +{ + AffineTransform imp(*impl()); + + float angle = args[0]->toFloat(exec); + return toJS(exec, new JSSVGPODTypeWrapperCreatorReadOnly<AffineTransform>(imp.skewX(angle)), m_context.get()); +} + +JSValue* JSSVGMatrix::skewY(ExecState* exec, const List& args) +{ + AffineTransform imp(*impl()); + + float angle = args[0]->toFloat(exec); + return toJS(exec, new JSSVGPODTypeWrapperCreatorReadOnly<AffineTransform>(imp.skewY(angle)), m_context.get()); +} + +} + +#endif // ENABLE(SVG) + +// vim:ts=4:noet diff --git a/WebCore/bindings/js/JSSVGPODTypeWrapper.h b/WebCore/bindings/js/JSSVGPODTypeWrapper.h new file mode 100644 index 0000000..1275950 --- /dev/null +++ b/WebCore/bindings/js/JSSVGPODTypeWrapper.h @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSSVGPODTypeWrapper_h +#define JSSVGPODTypeWrapper_h + +#if ENABLE(SVG) + +#include "Frame.h" +#include <wtf/RefCounted.h> +#include "SVGElement.h" + +#include <wtf/Assertions.h> +#include <wtf/HashMap.h> + +namespace WebCore { + +template<typename PODType> +class JSSVGPODTypeWrapper : public RefCounted<JSSVGPODTypeWrapper<PODType> > { +public: + JSSVGPODTypeWrapper() : RefCounted<JSSVGPODTypeWrapper<PODType> >(0) { } + virtual ~JSSVGPODTypeWrapper() { } + + // Getter wrapper + virtual operator PODType() = 0; + + // Setter wrapper + virtual void commitChange(PODType, SVGElement*) = 0; +}; + +template<typename PODType, typename PODTypeCreator> +class JSSVGPODTypeWrapperCreatorReadWrite : public JSSVGPODTypeWrapper<PODType> +{ +public: + typedef PODType (PODTypeCreator::*GetterMethod)() const; + typedef void (PODTypeCreator::*SetterMethod)(PODType); + + JSSVGPODTypeWrapperCreatorReadWrite(PODTypeCreator* creator, GetterMethod getter, SetterMethod setter) + : m_creator(creator) + , m_getter(getter) + , m_setter(setter) + { + ASSERT(creator); + ASSERT(getter); + ASSERT(setter); + } + + virtual ~JSSVGPODTypeWrapperCreatorReadWrite() { } + + // Getter wrapper + virtual operator PODType() { return (m_creator.get()->*m_getter)(); } + + // Setter wrapper + virtual void commitChange(PODType type, SVGElement* context) + { + if (!m_setter) + return; + + (m_creator.get()->*m_setter)(type); + + if (context) + context->svgAttributeChanged(m_creator->associatedAttributeName()); + } + +private: + // Update callbacks + RefPtr<PODTypeCreator> m_creator; + GetterMethod m_getter; + SetterMethod m_setter; +}; + +template<typename PODType> +class JSSVGPODTypeWrapperCreatorReadOnly : public JSSVGPODTypeWrapper<PODType> +{ +public: + JSSVGPODTypeWrapperCreatorReadOnly(PODType type) + : m_podType(type) + { } + + virtual ~JSSVGPODTypeWrapperCreatorReadOnly() { } + + // Getter wrapper + virtual operator PODType() { return m_podType; } + + // Setter wrapper + virtual void commitChange(PODType type, SVGElement*) + { + m_podType = type; + } + +private: + PODType m_podType; +}; + +template<typename PODType> +class SVGPODListItem; + +template<typename PODType> +class JSSVGPODTypeWrapperCreatorForList : public JSSVGPODTypeWrapper<PODType> +{ +public: + typedef PODType (SVGPODListItem<PODType>::*GetterMethod)() const; + typedef void (SVGPODListItem<PODType>::*SetterMethod)(PODType); + + JSSVGPODTypeWrapperCreatorForList(SVGPODListItem<PODType>* creator, const QualifiedName& attributeName) + : m_creator(creator) + , m_getter(&SVGPODListItem<PODType>::value) + , m_setter(&SVGPODListItem<PODType>::setValue) + , m_associatedAttributeName(attributeName) + { + ASSERT(m_creator); + ASSERT(m_getter); + ASSERT(m_setter); + } + + virtual ~JSSVGPODTypeWrapperCreatorForList() { } + + // Getter wrapper + virtual operator PODType() { return (m_creator.get()->*m_getter)(); } + + // Setter wrapper + virtual void commitChange(PODType type, SVGElement* context) + { + if (!m_setter) + return; + + (m_creator.get()->*m_setter)(type); + + if (context) + context->svgAttributeChanged(m_associatedAttributeName); + } + +private: + // Update callbacks + RefPtr<SVGPODListItem<PODType> > m_creator; + GetterMethod m_getter; + SetterMethod m_setter; + const QualifiedName& m_associatedAttributeName; +}; + +// Caching facilities +template<typename PODType, typename PODTypeCreator> +struct PODTypeReadWriteHashInfo { + typedef PODType (PODTypeCreator::*GetterMethod)() const; + typedef void (PODTypeCreator::*SetterMethod)(PODType); + + // Empty value + PODTypeReadWriteHashInfo() + : creator(0) + , getter(0) + , setter(0) + { } + + // Deleted value + explicit PODTypeReadWriteHashInfo(bool) + : creator(reinterpret_cast<PODTypeCreator*>(-1)) + , getter(0) + , setter(0) + { } + + PODTypeReadWriteHashInfo(PODTypeCreator* _creator, GetterMethod _getter, SetterMethod _setter) + : creator(_creator) + , getter(_getter) + , setter(_setter) + { + ASSERT(creator); + ASSERT(getter); + } + + bool operator==(const PODTypeReadWriteHashInfo& other) const + { + return creator == other.creator && getter == other.getter && setter == other.setter; + } + + PODTypeCreator* creator; + GetterMethod getter; + SetterMethod setter; +}; + +template<typename PODType, typename PODTypeCreator> +struct PODTypeReadWriteHashInfoHash { + static unsigned hash(const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& info) + { + return StringImpl::computeHash((::UChar*) &info, sizeof(PODTypeReadWriteHashInfo<PODType, PODTypeCreator>) / sizeof(::UChar)); + } + + static bool equal(const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& a, const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& b) + { + return a == b; + } + + static const bool safeToCompareToEmptyOrDeleted = true; +}; + +template<typename PODType, typename PODTypeCreator> +struct PODTypeReadWriteHashInfoTraits : WTF::GenericHashTraits<PODTypeReadWriteHashInfo<PODType, PODTypeCreator> > { + static const bool emptyValueIsZero = true; + static const bool needsDestruction = false; + + static const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& deletedValue() + { + static PODTypeReadWriteHashInfo<PODType, PODTypeCreator> key(true); + return key; + } + + static const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& emptyValue() + { + static PODTypeReadWriteHashInfo<PODType, PODTypeCreator> key; + return key; + } +}; + +template<typename PODType, typename PODTypeCreator> +class JSSVGPODTypeWrapperCache +{ +public: + typedef PODType (PODTypeCreator::*GetterMethod)() const; + typedef void (PODTypeCreator::*SetterMethod)(PODType); + + typedef HashMap<PODTypeReadWriteHashInfo<PODType, PODTypeCreator>, JSSVGPODTypeWrapperCreatorReadWrite<PODType, PODTypeCreator>*, PODTypeReadWriteHashInfoHash<PODType, PODTypeCreator>, PODTypeReadWriteHashInfoTraits<PODType, PODTypeCreator> > ReadWriteHashMap; + typedef typename ReadWriteHashMap::const_iterator ReadWriteHashMapIterator; + + static ReadWriteHashMap& readWriteHashMap() + { + static ReadWriteHashMap _readWriteHashMap; + return _readWriteHashMap; + } + + // Used for readwrite attributes only + static JSSVGPODTypeWrapper<PODType>* lookupOrCreateWrapper(PODTypeCreator* creator, GetterMethod getter, SetterMethod setter) + { + ReadWriteHashMap& map(readWriteHashMap()); + PODTypeReadWriteHashInfo<PODType, PODTypeCreator> info(creator, getter, setter); + + if (map.contains(info)) + return map.get(info); + + JSSVGPODTypeWrapperCreatorReadWrite<PODType, PODTypeCreator>* wrapper = new JSSVGPODTypeWrapperCreatorReadWrite<PODType, PODTypeCreator>(creator, getter, setter); + map.set(info, wrapper); + return wrapper; + } + + static void forgetWrapper(JSSVGPODTypeWrapper<PODType>* wrapper) + { + ReadWriteHashMap& map(readWriteHashMap()); + + ReadWriteHashMapIterator it = map.begin(); + ReadWriteHashMapIterator end = map.end(); + + for (; it != end; ++it) { + if (it->second != wrapper) + continue; + + // It's guaruanteed that there's just one object we need to take care of. + map.remove(it->first); + break; + } + } +}; + +}; + +#endif // ENABLE(SVG) +#endif // JSSVGPODTypeWrapper_h diff --git a/WebCore/bindings/js/JSSVGPathSegCustom.cpp b/WebCore/bindings/js/JSSVGPathSegCustom.cpp new file mode 100644 index 0000000..55db3a1 --- /dev/null +++ b/WebCore/bindings/js/JSSVGPathSegCustom.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#if ENABLE(SVG) +#include "JSSVGPathSeg.h" +#include "JSSVGPathSegArcAbs.h" +#include "JSSVGPathSegArcRel.h" +#include "JSSVGPathSegClosePath.h" +#include "JSSVGPathSegCurvetoCubicAbs.h" +#include "JSSVGPathSegCurvetoCubicRel.h" +#include "JSSVGPathSegCurvetoCubicSmoothAbs.h" +#include "JSSVGPathSegCurvetoCubicSmoothRel.h" +#include "JSSVGPathSegCurvetoQuadraticAbs.h" +#include "JSSVGPathSegCurvetoQuadraticRel.h" +#include "JSSVGPathSegCurvetoQuadraticSmoothAbs.h" +#include "JSSVGPathSegCurvetoQuadraticSmoothRel.h" +#include "JSSVGPathSegLinetoAbs.h" +#include "JSSVGPathSegLinetoRel.h" +#include "JSSVGPathSegLinetoHorizontalAbs.h" +#include "JSSVGPathSegLinetoHorizontalRel.h" +#include "JSSVGPathSegLinetoVerticalAbs.h" +#include "JSSVGPathSegLinetoVerticalRel.h" +#include "JSSVGPathSegMovetoAbs.h" +#include "JSSVGPathSegMovetoRel.h" + +#include "kjs_binding.h" + +#include "SVGPathSeg.h" +#include "SVGPathSegArc.h" +#include "SVGPathSegClosePath.h" +#include "SVGPathSegCurvetoCubic.h" +#include "SVGPathSegCurvetoCubicSmooth.h" +#include "SVGPathSegCurvetoQuadratic.h" +#include "SVGPathSegCurvetoQuadraticSmooth.h" +#include "SVGPathSegLineto.h" +#include "SVGPathSegLinetoHorizontal.h" +#include "SVGPathSegLinetoVertical.h" +#include "SVGPathSegMoveto.h" + +using namespace KJS; + +namespace WebCore { + +JSValue* toJS(ExecState* exec, SVGPathSeg* obj, SVGElement* context) +{ + if (!obj) + return jsNull(); + + switch (obj->pathSegType()) { + case SVGPathSeg::PATHSEG_CLOSEPATH: + return cacheSVGDOMObject<SVGPathSegClosePath, JSSVGPathSegClosePath, JSSVGPathSegClosePathPrototype>(exec, static_cast<SVGPathSegClosePath*>(obj), context); + case SVGPathSeg::PATHSEG_MOVETO_ABS: + return cacheSVGDOMObject<SVGPathSegMovetoAbs, JSSVGPathSegMovetoAbs, JSSVGPathSegMovetoAbsPrototype>(exec, static_cast<SVGPathSegMovetoAbs*>(obj), context); + case SVGPathSeg::PATHSEG_MOVETO_REL: + return cacheSVGDOMObject<SVGPathSegMovetoRel, JSSVGPathSegMovetoRel, JSSVGPathSegMovetoRelPrototype>(exec, static_cast<SVGPathSegMovetoRel*>(obj), context); + case SVGPathSeg::PATHSEG_LINETO_ABS: + return cacheSVGDOMObject<SVGPathSegLinetoAbs, JSSVGPathSegLinetoAbs, JSSVGPathSegLinetoAbsPrototype>(exec, static_cast<SVGPathSegLinetoAbs*>(obj), context); + case SVGPathSeg::PATHSEG_LINETO_REL: + return cacheSVGDOMObject<SVGPathSegLinetoRel, JSSVGPathSegLinetoRel, JSSVGPathSegLinetoRelPrototype>(exec, static_cast<SVGPathSegLinetoRel*>(obj), context); + case SVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS: + return cacheSVGDOMObject<SVGPathSegCurvetoCubicAbs, JSSVGPathSegCurvetoCubicAbs, JSSVGPathSegCurvetoCubicAbsPrototype>(exec, static_cast<SVGPathSegCurvetoCubicAbs*>(obj), context); + case SVGPathSeg::PATHSEG_CURVETO_CUBIC_REL: + return cacheSVGDOMObject<SVGPathSegCurvetoCubicRel, JSSVGPathSegCurvetoCubicRel, JSSVGPathSegCurvetoCubicRelPrototype>(exec, static_cast<SVGPathSegCurvetoCubicRel*>(obj), context); + case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_ABS: + return cacheSVGDOMObject<SVGPathSegCurvetoQuadraticAbs, JSSVGPathSegCurvetoQuadraticAbs, JSSVGPathSegCurvetoQuadraticAbsPrototype>(exec, static_cast<SVGPathSegCurvetoQuadraticAbs*>(obj), context); + case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_REL: + return cacheSVGDOMObject<SVGPathSegCurvetoQuadraticRel, JSSVGPathSegCurvetoQuadraticRel, JSSVGPathSegCurvetoQuadraticRelPrototype>(exec, static_cast<SVGPathSegCurvetoQuadraticRel*>(obj), context); + case SVGPathSeg::PATHSEG_ARC_ABS: + return cacheSVGDOMObject<SVGPathSegArcAbs, JSSVGPathSegArcAbs, JSSVGPathSegArcAbsPrototype>(exec, static_cast<SVGPathSegArcAbs*>(obj), context); + case SVGPathSeg::PATHSEG_ARC_REL: + return cacheSVGDOMObject<SVGPathSegArcRel, JSSVGPathSegArcRel, JSSVGPathSegArcRelPrototype>(exec, static_cast<SVGPathSegArcRel*>(obj), context); + case SVGPathSeg::PATHSEG_LINETO_HORIZONTAL_ABS: + return cacheSVGDOMObject<SVGPathSegLinetoHorizontalAbs, JSSVGPathSegLinetoHorizontalAbs, JSSVGPathSegLinetoHorizontalAbsPrototype>(exec, static_cast<SVGPathSegLinetoHorizontalAbs*>(obj), context); + case SVGPathSeg::PATHSEG_LINETO_HORIZONTAL_REL: + return cacheSVGDOMObject<SVGPathSegLinetoHorizontalRel, JSSVGPathSegLinetoHorizontalRel, JSSVGPathSegLinetoHorizontalRelPrototype>(exec, static_cast<SVGPathSegLinetoHorizontalRel*>(obj), context); + case SVGPathSeg::PATHSEG_LINETO_VERTICAL_ABS: + return cacheSVGDOMObject<SVGPathSegLinetoVerticalAbs, JSSVGPathSegLinetoVerticalAbs, JSSVGPathSegLinetoVerticalAbsPrototype>(exec, static_cast<SVGPathSegLinetoVerticalAbs*>(obj), context); + case SVGPathSeg::PATHSEG_LINETO_VERTICAL_REL: + return cacheSVGDOMObject<SVGPathSegLinetoVerticalRel, JSSVGPathSegLinetoVerticalRel, JSSVGPathSegLinetoVerticalRelPrototype>(exec, static_cast<SVGPathSegLinetoVerticalRel*>(obj), context); + case SVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_ABS: + return cacheSVGDOMObject<SVGPathSegCurvetoCubicSmoothAbs, JSSVGPathSegCurvetoCubicSmoothAbs, JSSVGPathSegCurvetoCubicSmoothAbsPrototype>(exec, static_cast<SVGPathSegCurvetoCubicSmoothAbs*>(obj), context); + case SVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_REL: + return cacheSVGDOMObject<SVGPathSegCurvetoCubicSmoothRel, JSSVGPathSegCurvetoCubicSmoothRel, JSSVGPathSegCurvetoCubicSmoothRelPrototype>(exec, static_cast<SVGPathSegCurvetoCubicSmoothRel*>(obj), context); + case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS: + return cacheSVGDOMObject<SVGPathSegCurvetoQuadraticSmoothAbs, JSSVGPathSegCurvetoQuadraticSmoothAbs, JSSVGPathSegCurvetoQuadraticSmoothAbsPrototype>(exec, static_cast<SVGPathSegCurvetoQuadraticSmoothAbs*>(obj), context); + case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL: + return cacheSVGDOMObject<SVGPathSegCurvetoQuadraticSmoothRel, JSSVGPathSegCurvetoQuadraticSmoothRel, JSSVGPathSegCurvetoQuadraticSmoothRelPrototype>(exec, static_cast<SVGPathSegCurvetoQuadraticSmoothRel*>(obj), context); + case SVGPathSeg::PATHSEG_UNKNOWN: + default: + return cacheSVGDOMObject<SVGPathSeg, JSSVGPathSeg, JSSVGPathSegPrototype>(exec, obj, context); + } +} + +} + +#endif // ENABLE(SVG) + +// vim:ts=4:noet diff --git a/WebCore/bindings/js/JSSVGPathSegListCustom.cpp b/WebCore/bindings/js/JSSVGPathSegListCustom.cpp new file mode 100644 index 0000000..19972a2 --- /dev/null +++ b/WebCore/bindings/js/JSSVGPathSegListCustom.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#if ENABLE(SVG) +#include "JSSVGPathSegList.h" + +#include "Document.h" +#include "Frame.h" +#include "JSSVGPathSeg.h" +#include "SVGDocumentExtensions.h" +#include "SVGElement.h" +#include "SVGPathSegList.h" + +#include <wtf/Assertions.h> + +using namespace KJS; + +namespace WebCore { + +JSValue* JSSVGPathSegList::clear(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + + SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); + imp->clear(ec); + + setDOMException(exec, ec); + + m_context->svgAttributeChanged(imp->associatedAttributeName()); + return jsUndefined(); +} + +JSValue* JSSVGPathSegList::initialize(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + SVGPathSeg* newItem = toSVGPathSeg(args[0]); + + SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); + + SVGPathSeg* obj = WTF::getPtr(imp->initialize(newItem, ec)); + + KJS::JSValue* result = toJS(exec, obj, m_context.get()); + setDOMException(exec, ec); + + m_context->svgAttributeChanged(imp->associatedAttributeName()); + return result; +} + +JSValue* JSSVGPathSegList::getItem(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + + bool indexOk; + unsigned index = args[0]->toInt32(exec, indexOk); + if (!indexOk) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); + SVGPathSeg* obj = WTF::getPtr(imp->getItem(index, ec)); + + KJS::JSValue* result = toJS(exec, obj, m_context.get()); + setDOMException(exec, ec); + return result; +} + +JSValue* JSSVGPathSegList::insertItemBefore(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + SVGPathSeg* newItem = toSVGPathSeg(args[0]); + + bool indexOk; + unsigned index = args[1]->toInt32(exec, indexOk); + if (!indexOk) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); + + KJS::JSValue* result = toJS(exec, WTF::getPtr(imp->insertItemBefore(newItem, index, ec)), m_context.get()); + setDOMException(exec, ec); + + m_context->svgAttributeChanged(imp->associatedAttributeName()); + return result; +} + +JSValue* JSSVGPathSegList::replaceItem(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + SVGPathSeg* newItem = toSVGPathSeg(args[0]); + + bool indexOk; + unsigned index = args[1]->toInt32(exec, indexOk); + if (!indexOk) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); + + KJS::JSValue* result = toJS(exec, WTF::getPtr(imp->replaceItem(newItem, index, ec)), m_context.get()); + setDOMException(exec, ec); + + m_context->svgAttributeChanged(imp->associatedAttributeName()); + return result; +} + +JSValue* JSSVGPathSegList::removeItem(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + + bool indexOk; + unsigned index = args[0]->toInt32(exec, indexOk); + if (!indexOk) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); + + RefPtr<SVGPathSeg> obj(imp->removeItem(index, ec)); + + KJS::JSValue* result = toJS(exec, obj.get(), m_context.get()); + setDOMException(exec, ec); + + m_context->svgAttributeChanged(imp->associatedAttributeName()); + return result; +} + +JSValue* JSSVGPathSegList::appendItem(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + SVGPathSeg* newItem = toSVGPathSeg(args[0]); + + SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); + + KJS::JSValue* result = toJS(exec, WTF::getPtr(imp->appendItem(newItem, ec)), m_context.get()); + setDOMException(exec, ec); + + m_context->svgAttributeChanged(imp->associatedAttributeName()); + return result; +} + +} + +#endif // ENABLE(SVG) diff --git a/WebCore/bindings/js/JSSVGPointListCustom.cpp b/WebCore/bindings/js/JSSVGPointListCustom.cpp new file mode 100644 index 0000000..af4fc91 --- /dev/null +++ b/WebCore/bindings/js/JSSVGPointListCustom.cpp @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#if ENABLE(SVG) +#include "JSSVGPointList.h" + +#include "Document.h" +#include "Frame.h" +#include "JSSVGPoint.h" +#include "SVGDocumentExtensions.h" +#include "SVGPointList.h" +#include "SVGStyledElement.h" + +#include <wtf/Assertions.h> + +using namespace KJS; + +namespace WebCore { + +JSValue* JSSVGPointList::clear(ExecState* exec, const List&) +{ + ExceptionCode ec = 0; + + SVGPointList* imp = static_cast<SVGPointList*>(impl()); + imp->clear(ec); + setDOMException(exec, ec); + + m_context->svgAttributeChanged(imp->associatedAttributeName()); + + return jsUndefined(); +} + +JSValue* JSSVGPointList::initialize(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + FloatPoint newItem = toSVGPoint(args[0]); + + SVGPointList* imp = static_cast<SVGPointList*>(impl()); + SVGList<RefPtr<SVGPODListItem<FloatPoint> > >* listImp = imp; + + SVGPODListItem<FloatPoint>* listItem = listImp->initialize(SVGPODListItem<FloatPoint>::copy(newItem), ec).get(); + JSSVGPODTypeWrapperCreatorForList<FloatPoint>* obj = new JSSVGPODTypeWrapperCreatorForList<FloatPoint>(listItem, imp->associatedAttributeName()); + + KJS::JSValue* result = toJS(exec, obj, m_context.get()); + setDOMException(exec, ec); + + m_context->svgAttributeChanged(imp->associatedAttributeName()); + + return result; +} + +JSValue* JSSVGPointList::getItem(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + + bool indexOk; + unsigned index = args[0]->toInt32(exec, indexOk); + if (!indexOk) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + SVGPointList* imp = static_cast<SVGPointList*>(impl()); + SVGList<RefPtr<SVGPODListItem<FloatPoint> > >* listImp = imp; + + SVGPODListItem<FloatPoint>* listItem = listImp->getItem(index, ec).get(); + JSSVGPODTypeWrapperCreatorForList<FloatPoint>* obj = new JSSVGPODTypeWrapperCreatorForList<FloatPoint>(listItem, imp->associatedAttributeName()); + + KJS::JSValue* result = toJS(exec, obj, m_context.get()); + setDOMException(exec, ec); + return result; +} + +JSValue* JSSVGPointList::insertItemBefore(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + FloatPoint newItem = toSVGPoint(args[0]); + + bool indexOk; + unsigned index = args[1]->toInt32(exec, indexOk); + if (!indexOk) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + SVGPointList* imp = static_cast<SVGPointList*>(impl()); + SVGList<RefPtr<SVGPODListItem<FloatPoint> > >* listImp = imp; + + SVGPODListItem<FloatPoint>* listItem = listImp->insertItemBefore(SVGPODListItem<FloatPoint>::copy(newItem), index, ec).get(); + JSSVGPODTypeWrapperCreatorForList<FloatPoint>* obj = new JSSVGPODTypeWrapperCreatorForList<FloatPoint>(listItem, imp->associatedAttributeName()); + + KJS::JSValue* result = toJS(exec, obj, m_context.get()); + setDOMException(exec, ec); + + m_context->svgAttributeChanged(imp->associatedAttributeName()); + + return result; +} + +JSValue* JSSVGPointList::replaceItem(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + FloatPoint newItem = toSVGPoint(args[0]); + + bool indexOk; + unsigned index = args[1]->toInt32(exec, indexOk); + if (!indexOk) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + SVGPointList* imp = static_cast<SVGPointList*>(impl()); + SVGList<RefPtr<SVGPODListItem<FloatPoint> > >* listImp = imp; + + SVGPODListItem<FloatPoint>* listItem = listImp->replaceItem(SVGPODListItem<FloatPoint>::copy(newItem), index, ec).get(); + JSSVGPODTypeWrapperCreatorForList<FloatPoint>* obj = new JSSVGPODTypeWrapperCreatorForList<FloatPoint>(listItem, imp->associatedAttributeName()); + + KJS::JSValue* result = toJS(exec, obj, m_context.get()); + setDOMException(exec, ec); + + m_context->svgAttributeChanged(imp->associatedAttributeName()); + + return result; +} + +JSValue* JSSVGPointList::removeItem(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + + bool indexOk; + unsigned index = args[0]->toInt32(exec, indexOk); + if (!indexOk) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + SVGPointList* imp = static_cast<SVGPointList*>(impl()); + SVGList<RefPtr<SVGPODListItem<FloatPoint> > >* listImp = imp; + + RefPtr<SVGPODListItem<FloatPoint> > listItem(listImp->removeItem(index, ec)); + JSSVGPODTypeWrapper<FloatPoint>* obj = new JSSVGPODTypeWrapperCreatorReadOnly<FloatPoint>(*listItem.get()); + + KJS::JSValue* result = toJS(exec, obj, m_context.get()); + setDOMException(exec, ec); + + m_context->svgAttributeChanged(imp->associatedAttributeName()); + + return result; +} + +JSValue* JSSVGPointList::appendItem(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + FloatPoint newItem = toSVGPoint(args[0]); + + SVGPointList* imp = static_cast<SVGPointList*>(impl()); + SVGList<RefPtr<SVGPODListItem<FloatPoint> > >* listImp = imp; + + SVGPODListItem<FloatPoint>* listItem = listImp->appendItem(SVGPODListItem<FloatPoint>::copy(newItem), ec).get(); + JSSVGPODTypeWrapperCreatorForList<FloatPoint>* obj = new JSSVGPODTypeWrapperCreatorForList<FloatPoint>(listItem, imp->associatedAttributeName()); + + KJS::JSValue* result = toJS(exec, obj, m_context.get()); + setDOMException(exec, ec); + + m_context->svgAttributeChanged(imp->associatedAttributeName()); + + return result; +} + +} + +#endif // ENABLE(SVG) diff --git a/WebCore/bindings/js/JSSVGTransformListCustom.cpp b/WebCore/bindings/js/JSSVGTransformListCustom.cpp new file mode 100644 index 0000000..d3d8d25 --- /dev/null +++ b/WebCore/bindings/js/JSSVGTransformListCustom.cpp @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#if ENABLE(SVG) +#include "JSSVGTransformList.h" + +#include "Document.h" +#include "Frame.h" +#include "JSSVGTransform.h" +#include "SVGDocumentExtensions.h" +#include "SVGTransformList.h" +#include "SVGStyledElement.h" + +#include <wtf/Assertions.h> + +using namespace KJS; + +namespace WebCore { + +JSValue* JSSVGTransformList::clear(ExecState* exec, const List&) +{ + ExceptionCode ec = 0; + + SVGTransformList* imp = static_cast<SVGTransformList*>(impl()); + imp->clear(ec); + setDOMException(exec, ec); + + m_context->svgAttributeChanged(imp->associatedAttributeName()); + + return jsUndefined(); +} + +JSValue* JSSVGTransformList::initialize(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + SVGTransform newItem = toSVGTransform(args[0]); + + SVGTransformList* imp = static_cast<SVGTransformList*>(impl()); + SVGList<RefPtr<SVGPODListItem<SVGTransform> > >* listImp = imp; + + SVGPODListItem<SVGTransform>* listItem = listImp->initialize(SVGPODListItem<SVGTransform>::copy(newItem), ec).get(); + JSSVGPODTypeWrapperCreatorForList<SVGTransform>* obj = new JSSVGPODTypeWrapperCreatorForList<SVGTransform>(listItem, imp->associatedAttributeName()); + + KJS::JSValue* result = toJS(exec, obj, m_context.get()); + setDOMException(exec, ec); + + m_context->svgAttributeChanged(imp->associatedAttributeName()); + + return result; +} + +JSValue* JSSVGTransformList::getItem(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + + bool indexOk; + unsigned index = args[0]->toInt32(exec, indexOk); + if (!indexOk) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + SVGTransformList* imp = static_cast<SVGTransformList*>(impl()); + SVGList<RefPtr<SVGPODListItem<SVGTransform> > >* listImp = imp; + + SVGPODListItem<SVGTransform>* listItem = listImp->getItem(index, ec).get(); + JSSVGPODTypeWrapperCreatorForList<SVGTransform>* obj = new JSSVGPODTypeWrapperCreatorForList<SVGTransform>(listItem, imp->associatedAttributeName()); + + KJS::JSValue* result = toJS(exec, obj, m_context.get()); + setDOMException(exec, ec); + return result; +} + +JSValue* JSSVGTransformList::insertItemBefore(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + SVGTransform newItem = toSVGTransform(args[0]); + + bool indexOk; + unsigned index = args[1]->toInt32(exec, indexOk); + if (!indexOk) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + SVGTransformList* imp = static_cast<SVGTransformList*>(impl()); + SVGList<RefPtr<SVGPODListItem<SVGTransform> > >* listImp = imp; + + SVGPODListItem<SVGTransform>* listItem = listImp->insertItemBefore(SVGPODListItem<SVGTransform>::copy(newItem), index, ec).get(); + JSSVGPODTypeWrapperCreatorForList<SVGTransform>* obj = new JSSVGPODTypeWrapperCreatorForList<SVGTransform>(listItem, imp->associatedAttributeName()); + + KJS::JSValue* result = toJS(exec, obj, m_context.get()); + setDOMException(exec, ec); + + m_context->svgAttributeChanged(imp->associatedAttributeName()); + + return result; +} + +JSValue* JSSVGTransformList::replaceItem(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + SVGTransform newItem = toSVGTransform(args[0]); + + bool indexOk; + unsigned index = args[1]->toInt32(exec, indexOk); + if (!indexOk) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + SVGTransformList* imp = static_cast<SVGTransformList*>(impl()); + SVGList<RefPtr<SVGPODListItem<SVGTransform> > >* listImp = imp; + + SVGPODListItem<SVGTransform>* listItem = listImp->replaceItem(SVGPODListItem<SVGTransform>::copy(newItem), index, ec).get(); + JSSVGPODTypeWrapperCreatorForList<SVGTransform>* obj = new JSSVGPODTypeWrapperCreatorForList<SVGTransform>(listItem, imp->associatedAttributeName()); + + KJS::JSValue* result = toJS(exec, obj, m_context.get()); + setDOMException(exec, ec); + + m_context->svgAttributeChanged(imp->associatedAttributeName()); + + return result; +} + +JSValue* JSSVGTransformList::removeItem(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + + bool indexOk; + unsigned index = args[0]->toInt32(exec, indexOk); + if (!indexOk) { + setDOMException(exec, TYPE_MISMATCH_ERR); + return jsUndefined(); + } + + SVGTransformList* imp = static_cast<SVGTransformList*>(impl()); + SVGList<RefPtr<SVGPODListItem<SVGTransform> > >* listImp = imp; + + RefPtr<SVGPODListItem<SVGTransform> > listItem(listImp->removeItem(index, ec)); + JSSVGPODTypeWrapper<SVGTransform>* obj = new JSSVGPODTypeWrapperCreatorReadOnly<SVGTransform>(*listItem.get()); + + KJS::JSValue* result = toJS(exec, obj, m_context.get()); + setDOMException(exec, ec); + + m_context->svgAttributeChanged(imp->associatedAttributeName()); + + return result; +} + +JSValue* JSSVGTransformList::appendItem(ExecState* exec, const List& args) +{ + ExceptionCode ec = 0; + SVGTransform newItem = toSVGTransform(args[0]); + + SVGTransformList* imp = static_cast<SVGTransformList*>(impl()); + SVGList<RefPtr<SVGPODListItem<SVGTransform> > >* listImp = imp; + + SVGPODListItem<SVGTransform>* listItem = listImp->appendItem(SVGPODListItem<SVGTransform>::copy(newItem), ec).get(); + JSSVGPODTypeWrapperCreatorForList<SVGTransform>* obj = new JSSVGPODTypeWrapperCreatorForList<SVGTransform>(listItem, imp->associatedAttributeName()); + + KJS::JSValue* result = toJS(exec, obj, m_context.get()); + setDOMException(exec, ec); + + m_context->svgAttributeChanged(imp->associatedAttributeName()); + + return result; +} + +} + +#endif // ENABLE(SVG) diff --git a/WebCore/bindings/js/JSStyleSheetCustom.cpp b/WebCore/bindings/js/JSStyleSheetCustom.cpp new file mode 100644 index 0000000..4122831 --- /dev/null +++ b/WebCore/bindings/js/JSStyleSheetCustom.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSStyleSheet.h" + +#include "CSSStyleSheet.h" +#include "JSCSSStyleSheet.h" +#include "StyleSheet.h" + +using namespace KJS; + +namespace WebCore { + +JSValue* toJS(ExecState* exec, StyleSheet* styleSheet) +{ + if (!styleSheet) + return jsNull(); + + DOMObject* ret = ScriptInterpreter::getDOMObject(styleSheet); + if (ret) + return ret; + + if (styleSheet->isCSSStyleSheet()) + ret = new JSCSSStyleSheet(JSCSSStyleSheetPrototype::self(exec), static_cast<CSSStyleSheet*>(styleSheet)); + else + ret = new JSStyleSheet(JSStyleSheetPrototype::self(exec), styleSheet); + + ScriptInterpreter::putDOMObject(styleSheet, ret); + return ret; +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSStyleSheetListCustom.cpp b/WebCore/bindings/js/JSStyleSheetListCustom.cpp new file mode 100644 index 0000000..aa4014f --- /dev/null +++ b/WebCore/bindings/js/JSStyleSheetListCustom.cpp @@ -0,0 +1,50 @@ + +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSStyleSheetList.h" + +#include "HTMLStyleElement.h" +#include "JSStyleSheet.h" +#include "StyleSheet.h" +#include "StyleSheetList.h" + +namespace WebCore { + +bool JSStyleSheetList::canGetItemsForName(KJS::ExecState*, StyleSheetList* styleSheetList, const KJS::Identifier& propertyName) +{ + return styleSheetList->getNamedItem(propertyName); +} + +KJS::JSValue* JSStyleSheetList::nameGetter(KJS::ExecState* exec, KJS::JSObject*, const KJS::Identifier& propertyName, const KJS::PropertySlot& slot) +{ + JSStyleSheetList* thisObj = static_cast<JSStyleSheetList*>(slot.slotBase()); + HTMLStyleElement* element = thisObj->impl()->getNamedItem(propertyName); + ASSERT(element); + return toJS(exec, element->sheet()); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSTreeWalkerCustom.cpp b/WebCore/bindings/js/JSTreeWalkerCustom.cpp new file mode 100644 index 0000000..c9dbcd9 --- /dev/null +++ b/WebCore/bindings/js/JSTreeWalkerCustom.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "JSTreeWalker.h" + +#include "JSNode.h" +#include "Node.h" +#include "NodeFilter.h" +#include "TreeWalker.h" + +using namespace KJS; + +namespace WebCore { + +void JSTreeWalker::mark() +{ + if (NodeFilter* filter = m_impl->filter()) + filter->mark(); + + DOMObject::mark(); +} + +JSValue* JSTreeWalker::parentNode(ExecState* exec, const List& args) +{ + JSValue* exception = 0; + Node* node = impl()->parentNode(exception); + if (exception) { + exec->setException(exception); + return jsUndefined(); + } + return toJS(exec, node); +} + +JSValue* JSTreeWalker::firstChild(ExecState* exec, const List& args) +{ + JSValue* exception = 0; + Node* node = impl()->firstChild(exception); + if (exception) { + exec->setException(exception); + return jsUndefined(); + } + return toJS(exec, node); +} + +JSValue* JSTreeWalker::lastChild(ExecState* exec, const List& args) +{ + JSValue* exception = 0; + Node* node = impl()->lastChild(exception); + if (exception) { + exec->setException(exception); + return jsUndefined(); + } + return toJS(exec, node); +} + +JSValue* JSTreeWalker::nextSibling(ExecState* exec, const List& args) +{ + JSValue* exception = 0; + Node* node = impl()->nextSibling(exception); + if (exception) { + exec->setException(exception); + return jsUndefined(); + } + return toJS(exec, node); +} + +JSValue* JSTreeWalker::previousSibling(ExecState* exec, const List& args) +{ + JSValue* exception = 0; + Node* node = impl()->previousSibling(exception); + if (exception) { + exec->setException(exception); + return jsUndefined(); + } + return toJS(exec, node); +} + +JSValue* JSTreeWalker::previousNode(ExecState* exec, const List& args) +{ + JSValue* exception = 0; + Node* node = impl()->previousNode(exception); + if (exception) { + exec->setException(exception); + return jsUndefined(); + } + return toJS(exec, node); +} + +JSValue* JSTreeWalker::nextNode(ExecState* exec, const List& args) +{ + JSValue* exception = 0; + Node* node = impl()->nextNode(exception); + if (exception) { + exec->setException(exception); + return jsUndefined(); + } + return toJS(exec, node); +} + +} diff --git a/WebCore/bindings/js/JSXMLHttpRequest.cpp b/WebCore/bindings/js/JSXMLHttpRequest.cpp new file mode 100644 index 0000000..99d89f5 --- /dev/null +++ b/WebCore/bindings/js/JSXMLHttpRequest.cpp @@ -0,0 +1,400 @@ +/* + * Copyright (C) 2004, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2005, 2006 Alexey Proskuryakov <ap@nypop.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "JSXMLHttpRequest.h" + +#include "DOMWindow.h" +#include "Event.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "HTMLDocument.h" +#include "JSDocument.h" +#include "JSEvent.h" +#include "XMLHttpRequest.h" +#include "kjs_events.h" +#include "kjs_window.h" + +using namespace KJS; +using namespace WebCore; + +#include "JSXMLHttpRequest.lut.h" + +namespace WebCore { + +/* Source for JSXMLHttpRequestPrototypeTable. +@begin JSXMLHttpRequestPrototypeTable 7 + abort jsXMLHttpRequestPrototypeFunctionAbort DontDelete|Function 0 + getAllResponseHeaders jsXMLHttpRequestPrototypeFunctionGetAllResponseHeaders DontDelete|Function 0 + getResponseHeader jsXMLHttpRequestPrototypeFunctionGetResponseHeader DontDelete|Function 1 + open jsXMLHttpRequestPrototypeFunctionOpen DontDelete|Function 5 + overrideMimeType jsXMLHttpRequestPrototypeFunctionOverrideMIMEType DontDelete|Function 1 + send jsXMLHttpRequestPrototypeFunctionSend DontDelete|Function 1 + setRequestHeader jsXMLHttpRequestPrototypeFunctionSetRequestHeader DontDelete|Function 2 +# from the EventTarget interface +# FIXME: add DOM3 EventTarget methods (addEventListenerNS, removeEventListenerNS). + addEventListener jsXMLHttpRequestPrototypeFunctionAddEventListener DontDelete|Function 3 + removeEventListener jsXMLHttpRequestPrototypeFunctionRemoveEventListener DontDelete|Function 3 + dispatchEvent jsXMLHttpRequestPrototypeFunctionDispatchEvent DontDelete|Function 1 +@end +*/ +KJS_DEFINE_PROTOTYPE(JSXMLHttpRequestPrototype) +KJS_IMPLEMENT_PROTOTYPE("JSXMLHttpRequest", JSXMLHttpRequestPrototype) + +JSXMLHttpRequestConstructorImp::JSXMLHttpRequestConstructorImp(ExecState* exec, Document* d) + : DOMObject(exec->lexicalGlobalObject()->objectPrototype()) + , doc(d) +{ + putDirect(exec->propertyNames().prototype, JSXMLHttpRequestPrototype::self(exec), None); +} + +bool JSXMLHttpRequestConstructorImp::implementsConstruct() const +{ + return true; +} + +JSObject* JSXMLHttpRequestConstructorImp::construct(ExecState* exec, const List&) +{ + return new JSXMLHttpRequest(JSXMLHttpRequestPrototype::self(exec), doc.get()); +} + +const ClassInfo JSXMLHttpRequest::info = { "JSXMLHttpRequest", 0, &JSXMLHttpRequestTable }; + +/* Source for JSXMLHttpRequestTable. +@begin JSXMLHttpRequestTable 7 + readyState JSXMLHttpRequest::ReadyState DontDelete|ReadOnly + responseText JSXMLHttpRequest::ResponseText DontDelete|ReadOnly + responseXML JSXMLHttpRequest::ResponseXML DontDelete|ReadOnly + status JSXMLHttpRequest::Status DontDelete|ReadOnly + statusText JSXMLHttpRequest::StatusText DontDelete|ReadOnly + onreadystatechange JSXMLHttpRequest::Onreadystatechange DontDelete + onload JSXMLHttpRequest::Onload DontDelete +@end +*/ + +bool JSXMLHttpRequest::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + return getStaticValueSlot<JSXMLHttpRequest, DOMObject>(exec, &JSXMLHttpRequestTable, this, propertyName, slot); +} + +JSValue* JSXMLHttpRequest::getValueProperty(ExecState* exec, int token) const +{ + ExceptionCode ec = 0; + + switch (token) { + case ReadyState: + return jsNumber(m_impl->getReadyState()); + case ResponseText: { + JSValue* result = jsOwnedStringOrNull(m_impl->getResponseText(ec)); + setDOMException(exec, ec); + return result; + } + case ResponseXML: { + Document* responseXML = m_impl->getResponseXML(ec); + setDOMException(exec, ec); + if (responseXML) + return toJS(exec, responseXML); + + return jsNull(); + } + case Status: { + JSValue* result = jsNumber(m_impl->getStatus(ec)); + setDOMException(exec, ec); + return result; + } + case StatusText: { + JSValue* result = jsString(m_impl->getStatusText(ec)); + setDOMException(exec, ec); + return result; + } + case Onreadystatechange: + if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->onReadyStateChangeListener())) + if (JSObject* listenerObj = listener->listenerObj()) + return listenerObj; + return jsNull(); + case Onload: + if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->onLoadListener())) + if (JSObject* listenerObj = listener->listenerObj()) + return listenerObj; + return jsNull(); + default: + return 0; + } +} + +void JSXMLHttpRequest::put(ExecState* exec, const Identifier& propertyName, JSValue* value) +{ + lookupPut<JSXMLHttpRequest, DOMObject>(exec, propertyName, value, &JSXMLHttpRequestTable, this); +} + +void JSXMLHttpRequest::putValueProperty(ExecState* exec, int token, JSValue* value) +{ + switch (token) { + case Onreadystatechange: { + Document* doc = m_impl->document(); + if (!doc) + return; + Frame* frame = doc->frame(); + if (!frame) + return; + m_impl->setOnReadyStateChangeListener(KJS::Window::retrieveWindow(frame)->findOrCreateJSUnprotectedEventListener(value, true)); + break; + } + case Onload: { + Document* doc = m_impl->document(); + if (!doc) + return; + Frame* frame = doc->frame(); + if (!frame) + return; + m_impl->setOnLoadListener(KJS::Window::retrieveWindow(frame)->findOrCreateJSUnprotectedEventListener(value, true)); + break; + } + } +} + +void JSXMLHttpRequest::mark() +{ + DOMObject::mark(); + + JSUnprotectedEventListener* onReadyStateChangeListener = static_cast<JSUnprotectedEventListener*>(m_impl->onReadyStateChangeListener()); + JSUnprotectedEventListener* onLoadListener = static_cast<JSUnprotectedEventListener*>(m_impl->onLoadListener()); + + if (onReadyStateChangeListener) + onReadyStateChangeListener->mark(); + + if (onLoadListener) + onLoadListener->mark(); + + typedef XMLHttpRequest::EventListenersMap EventListenersMap; + typedef XMLHttpRequest::ListenerVector ListenerVector; + EventListenersMap& eventListeners = m_impl->eventListeners(); + for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { + for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) { + JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(vecIter->get()); + listener->mark(); + } + } +} + + +JSXMLHttpRequest::JSXMLHttpRequest(JSObject* prototype, Document* d) + : DOMObject(prototype) + , m_impl(XMLHttpRequest::create(d)) +{ + ScriptInterpreter::putDOMObject(m_impl.get(), this); +} + +JSXMLHttpRequest::~JSXMLHttpRequest() +{ + m_impl->setOnReadyStateChangeListener(0); + m_impl->setOnLoadListener(0); + m_impl->eventListeners().clear(); + ScriptInterpreter::forgetDOMObject(m_impl.get()); +} + +JSValue* jsXMLHttpRequestPrototypeFunctionAbort(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSXMLHttpRequest::info)) + return throwError(exec, TypeError); + + JSXMLHttpRequest* request = static_cast<JSXMLHttpRequest*>(thisObj); + + request->impl()->abort(); + return jsUndefined(); +} + +JSValue* jsXMLHttpRequestPrototypeFunctionGetAllResponseHeaders(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSXMLHttpRequest::info)) + return throwError(exec, TypeError); + + JSXMLHttpRequest* request = static_cast<JSXMLHttpRequest*>(thisObj); + ExceptionCode ec = 0; + + JSValue* headers = jsStringOrUndefined(request->impl()->getAllResponseHeaders(ec)); + setDOMException(exec, ec); + return headers; +} + +JSValue* jsXMLHttpRequestPrototypeFunctionGetResponseHeader(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSXMLHttpRequest::info)) + return throwError(exec, TypeError); + + JSXMLHttpRequest* request = static_cast<JSXMLHttpRequest*>(thisObj); + ExceptionCode ec = 0; + + if (args.size() < 1) + return throwError(exec, SyntaxError, "Not enough arguments"); + + JSValue* header = jsStringOrNull(request->impl()->getResponseHeader(args[0]->toString(exec), ec)); + setDOMException(exec, ec); + return header; +} + +JSValue* jsXMLHttpRequestPrototypeFunctionOpen(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSXMLHttpRequest::info)) + return throwError(exec, TypeError); + + JSXMLHttpRequest* request = static_cast<JSXMLHttpRequest*>(thisObj); + ExceptionCode ec = 0; + + if (args.size() < 2) + return throwError(exec, SyntaxError, "Not enough arguments"); + + String method = args[0]->toString(exec); + Frame* frame = Window::retrieveActive(exec)->impl()->frame(); + if (!frame) + return jsUndefined(); + KURL url = frame->loader()->completeURL(args[1]->toString(exec)); + + bool async = true; + if (args.size() >= 3) + async = args[2]->toBoolean(exec); + + if (args.size() >= 4 && !args[3]->isUndefined()) { + String user = valueToStringWithNullCheck(exec, args[3]); + + if (args.size() >= 5 && !args[4]->isUndefined()) { + String password = valueToStringWithNullCheck(exec, args[4]); + request->impl()->open(method, url, async, user, password, ec); + } else + request->impl()->open(method, url, async, user, ec); + } else + request->impl()->open(method, url, async, ec); + + setDOMException(exec, ec); + return jsUndefined(); +} + +JSValue* jsXMLHttpRequestPrototypeFunctionSend(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSXMLHttpRequest::info)) + return throwError(exec, TypeError); + + JSXMLHttpRequest* request = static_cast<JSXMLHttpRequest*>(thisObj); + ExceptionCode ec = 0; + + String body; + + if (args.size() >= 1) { + if (args[0]->toObject(exec)->inherits(&JSDocument::info)) + body = static_cast<Document*>(static_cast<JSDocument*>(args[0]->toObject(exec))->impl())->toString(); + else { + // converting certain values (like null) to object can set an exception + if (exec->hadException()) + exec->clearException(); + else + body = args[0]->toString(exec); + } + } + + request->impl()->send(body, ec); + setDOMException(exec, ec); + + return jsUndefined(); +} + +JSValue* jsXMLHttpRequestPrototypeFunctionSetRequestHeader(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSXMLHttpRequest::info)) + return throwError(exec, TypeError); + + JSXMLHttpRequest* request = static_cast<JSXMLHttpRequest*>(thisObj); + ExceptionCode ec = 0; + + if (args.size() < 2) + return throwError(exec, SyntaxError, "Not enough arguments"); + + request->impl()->setRequestHeader(args[0]->toString(exec), args[1]->toString(exec), ec); + setDOMException(exec, ec); + return jsUndefined(); + +} + +JSValue* jsXMLHttpRequestPrototypeFunctionOverrideMIMEType(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSXMLHttpRequest::info)) + return throwError(exec, TypeError); + + JSXMLHttpRequest* request = static_cast<JSXMLHttpRequest*>(thisObj); + + if (args.size() < 1) + return throwError(exec, SyntaxError, "Not enough arguments"); + + request->impl()->overrideMIMEType(args[0]->toString(exec)); + return jsUndefined(); +} + +JSValue* jsXMLHttpRequestPrototypeFunctionAddEventListener(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSXMLHttpRequest::info)) + return throwError(exec, TypeError); + + JSXMLHttpRequest* request = static_cast<JSXMLHttpRequest*>(thisObj); + + Document* doc = request->impl()->document(); + if (!doc) + return jsUndefined(); + Frame* frame = doc->frame(); + if (!frame) + return jsUndefined(); + JSUnprotectedEventListener* listener = KJS::Window::retrieveWindow(frame)->findOrCreateJSUnprotectedEventListener(args[1], true); + if (!listener) + return jsUndefined(); + request->impl()->addEventListener(args[0]->toString(exec), listener, args[2]->toBoolean(exec)); + return jsUndefined(); +} + +JSValue* jsXMLHttpRequestPrototypeFunctionRemoveEventListener(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSXMLHttpRequest::info)) + return throwError(exec, TypeError); + + JSXMLHttpRequest* request = static_cast<JSXMLHttpRequest*>(thisObj); + + Document* doc = request->impl()->document(); + if (!doc) + return jsUndefined(); + Frame* frame = doc->frame(); + if (!frame) + return jsUndefined(); + JSUnprotectedEventListener* listener = KJS::Window::retrieveWindow(frame)->findOrCreateJSUnprotectedEventListener(args[1], true); + if (!listener) + return jsUndefined(); + request->impl()->removeEventListener(args[0]->toString(exec), listener, args[2]->toBoolean(exec)); + return jsUndefined(); +} + +JSValue* jsXMLHttpRequestPrototypeFunctionDispatchEvent(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSXMLHttpRequest::info)) + return throwError(exec, TypeError); + + JSXMLHttpRequest* request = static_cast<JSXMLHttpRequest*>(thisObj); + ExceptionCode ec = 0; + + bool result = request->impl()->dispatchEvent(toEvent(args[0]), ec); + setDOMException(exec, ec); + return jsBoolean(result); +} + +} // end namespace diff --git a/WebCore/bindings/js/JSXMLHttpRequest.h b/WebCore/bindings/js/JSXMLHttpRequest.h new file mode 100644 index 0000000..6567a6b --- /dev/null +++ b/WebCore/bindings/js/JSXMLHttpRequest.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2005, 2006 Alexey Proskuryakov <ap@nypop.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef JSXMLHttpRequest_h +#define JSXMLHttpRequest_h + +#include "kjs_binding.h" + +namespace WebCore { + +class XMLHttpRequest; +class Document; + +class JSXMLHttpRequestConstructorImp : public DOMObject { +public: + JSXMLHttpRequestConstructorImp(KJS::ExecState*, Document*); + + virtual bool implementsConstruct() const; + virtual KJS::JSObject* construct(KJS::ExecState*, const KJS::List&); + +private: + RefPtr<Document> doc; +}; + +class JSXMLHttpRequest : public DOMObject { +public: + JSXMLHttpRequest(KJS::JSObject* prototype, Document*); + ~JSXMLHttpRequest(); + + virtual const KJS::ClassInfo* classInfo() const { return &info; } + static const KJS::ClassInfo info; + enum { Onload, Onreadystatechange, ReadyState, ResponseText, ResponseXML, Status, + StatusText, Abort, GetAllResponseHeaders, GetResponseHeader, Open, Send, SetRequestHeader, OverrideMIMEType, + AddEventListener, RemoveEventListener, DispatchEvent }; + + virtual bool getOwnPropertySlot(KJS::ExecState*, const KJS::Identifier&, KJS::PropertySlot&); + KJS::JSValue* getValueProperty(KJS::ExecState*, int token) const; + virtual void put(KJS::ExecState*, const KJS::Identifier& propertyName, KJS::JSValue*); + void putValueProperty(KJS::ExecState*, int token, KJS::JSValue*); + virtual bool toBoolean(KJS::ExecState*) const { return true; } + virtual void mark(); + + XMLHttpRequest* impl() const { return m_impl.get(); } + +private: + RefPtr<XMLHttpRequest> m_impl; +}; + +KJS::JSValue* jsXMLHttpRequestPrototypeFunctionAbort(KJS::ExecState*, KJS::JSObject*, const KJS::List&); +KJS::JSValue* jsXMLHttpRequestPrototypeFunctionGetAllResponseHeaders(KJS::ExecState*, KJS::JSObject*, const KJS::List&); +KJS::JSValue* jsXMLHttpRequestPrototypeFunctionGetResponseHeader(KJS::ExecState*, KJS::JSObject*, const KJS::List&); +KJS::JSValue* jsXMLHttpRequestPrototypeFunctionOpen(KJS::ExecState*, KJS::JSObject*, const KJS::List&); +KJS::JSValue* jsXMLHttpRequestPrototypeFunctionSend(KJS::ExecState*, KJS::JSObject*, const KJS::List&); +KJS::JSValue* jsXMLHttpRequestPrototypeFunctionSetRequestHeader(KJS::ExecState*, KJS::JSObject*, const KJS::List&); +KJS::JSValue* jsXMLHttpRequestPrototypeFunctionOverrideMIMEType(KJS::ExecState*, KJS::JSObject*, const KJS::List&); +KJS::JSValue* jsXMLHttpRequestPrototypeFunctionAddEventListener(KJS::ExecState*, KJS::JSObject*, const KJS::List&); +KJS::JSValue* jsXMLHttpRequestPrototypeFunctionRemoveEventListener(KJS::ExecState*, KJS::JSObject*, const KJS::List&); +KJS::JSValue* jsXMLHttpRequestPrototypeFunctionDispatchEvent(KJS::ExecState*, KJS::JSObject*, const KJS::List&); + +} // namespace WebCore + +#endif // JSXMLHttpRequest_h diff --git a/WebCore/bindings/js/JSXSLTProcessor.cpp b/WebCore/bindings/js/JSXSLTProcessor.cpp new file mode 100644 index 0000000..7902f61 --- /dev/null +++ b/WebCore/bindings/js/JSXSLTProcessor.cpp @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(XSLT) + +#include "JSXSLTProcessor.h" + +#include "XSLTProcessor.h" +#include "kjs_dom.h" +#include "JSDocument.h" +#include "Document.h" +#include "DocumentFragment.h" + +using namespace KJS; +using namespace WebCore; + +#include "JSXSLTProcessor.lut.h" + +namespace WebCore { + +const ClassInfo JSXSLTProcessor::info = { "XSLTProcessor", 0, 0 }; + +/* +@begin XSLTProcessorPrototypeTable 7 + importStylesheet jsXSLTProcessorPrototypeFunctionImportStylesheet DontDelete|Function 1 + transformToFragment jsXSLTProcessorPrototypeFunctionTransformToFragment DontDelete|Function 2 + transformToDocument jsXSLTProcessorPrototypeFunctionTransformToDocument DontDelete|Function 2 + setParameter jsXSLTProcessorPrototypeFunctionSetParameter DontDelete|Function 3 + getParameter jsXSLTProcessorPrototypeFunctionGetParameter DontDelete|Function 2 + removeParameter jsXSLTProcessorPrototypeFunctionRemoveParameter DontDelete|Function 2 + clearParameters jsXSLTProcessorPrototypeFunctionClearParameters DontDelete|Function 0 + reset jsXSLTProcessorPrototypeFunctionReset DontDelete|Function 0 +@end +*/ + +KJS_DEFINE_PROTOTYPE(XSLTProcessorPrototype) +KJS_IMPLEMENT_PROTOTYPE("XSLTProcessor", XSLTProcessorPrototype) + +JSXSLTProcessor::JSXSLTProcessor(JSObject* prototype) + : DOMObject(prototype) + , m_impl(XSLTProcessor::create()) +{ +} + +JSXSLTProcessor::~JSXSLTProcessor() +{ + ScriptInterpreter::forgetDOMObject(m_impl.get()); +} + +JSValue* jsXSLTProcessorPrototypeFunctionImportStylesheet(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSXSLTProcessor::info)) + return throwError(exec, TypeError); + XSLTProcessor& processor = *static_cast<JSXSLTProcessor*>(thisObj)->impl(); + + JSValue *nodeVal = args[0]; + if (nodeVal->isObject(&JSNode::info)) { + JSNode* node = static_cast<JSNode*>(nodeVal); + processor.importStylesheet(node->impl()); + return jsUndefined(); + } + // Throw exception? + return jsUndefined(); +} + +JSValue* jsXSLTProcessorPrototypeFunctionTransformToFragment(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSXSLTProcessor::info)) + return throwError(exec, TypeError); + XSLTProcessor& processor = *static_cast<JSXSLTProcessor*>(thisObj)->impl(); + + JSValue *nodeVal = args[0]; + JSValue *docVal = args[1]; + if (nodeVal->isObject(&JSNode::info) && docVal->isObject(&JSDocument::info)) { + WebCore::Node* node = static_cast<JSNode*>(nodeVal)->impl(); + Document* doc = static_cast<Document*>(static_cast<JSDocument *>(docVal)->impl()); + return toJS(exec, processor.transformToFragment(node, doc).get()); + } + // Throw exception? + return jsUndefined(); +} + +JSValue* jsXSLTProcessorPrototypeFunctionTransformToDocument(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSXSLTProcessor::info)) + return throwError(exec, TypeError); + XSLTProcessor& processor = *static_cast<JSXSLTProcessor*>(thisObj)->impl(); + + JSValue *nodeVal = args[0]; + if (nodeVal->isObject(&JSNode::info)) { + JSNode* node = static_cast<JSNode*>(nodeVal); + RefPtr<Document> resultDocument = processor.transformToDocument(node->impl()); + if (resultDocument) + return toJS(exec, resultDocument.get()); + return jsUndefined(); + } + // Throw exception? + return jsUndefined(); +} + +JSValue* jsXSLTProcessorPrototypeFunctionSetParameter(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSXSLTProcessor::info)) + return throwError(exec, TypeError); + XSLTProcessor& processor = *static_cast<JSXSLTProcessor*>(thisObj)->impl(); + + if (args[1]->isUndefinedOrNull() || args[2]->isUndefinedOrNull()) + return jsUndefined(); // Throw exception? + String namespaceURI = args[0]->toString(exec); + String localName = args[1]->toString(exec); + String value = args[2]->toString(exec); + processor.setParameter(namespaceURI, localName, value); + return jsUndefined(); +} + +JSValue* jsXSLTProcessorPrototypeFunctionGetParameter(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSXSLTProcessor::info)) + return throwError(exec, TypeError); + XSLTProcessor& processor = *static_cast<JSXSLTProcessor*>(thisObj)->impl(); + + if (args[1]->isUndefinedOrNull()) + return jsUndefined(); + String namespaceURI = args[0]->toString(exec); + String localName = args[1]->toString(exec); + String value = processor.getParameter(namespaceURI, localName); + if (!value.isNull()) + return jsString(value); + return jsUndefined(); +} + +JSValue* jsXSLTProcessorPrototypeFunctionRemoveParameter(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSXSLTProcessor::info)) + return throwError(exec, TypeError); + XSLTProcessor& processor = *static_cast<JSXSLTProcessor*>(thisObj)->impl(); + + if (args[1]->isUndefinedOrNull()) + return jsUndefined(); + String namespaceURI = args[0]->toString(exec); + String localName = args[1]->toString(exec); + processor.removeParameter(namespaceURI, localName); + return jsUndefined(); +} + +JSValue* jsXSLTProcessorPrototypeFunctionClearParameters(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSXSLTProcessor::info)) + return throwError(exec, TypeError); + XSLTProcessor& processor = *static_cast<JSXSLTProcessor*>(thisObj)->impl(); + + processor.clearParameters(); + return jsUndefined(); +} + +JSValue* jsXSLTProcessorPrototypeFunctionReset(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSXSLTProcessor::info)) + return throwError(exec, TypeError); + XSLTProcessor& processor = *static_cast<JSXSLTProcessor*>(thisObj)->impl(); + + processor.reset(); + return jsUndefined(); +} + +XSLTProcessorConstructorImp::XSLTProcessorConstructorImp(ExecState* exec) + : DOMObject(exec->lexicalGlobalObject()->objectPrototype()) +{ + putDirect(exec->propertyNames().prototype, XSLTProcessorPrototype::self(exec), None); +} + +bool XSLTProcessorConstructorImp::implementsConstruct() const +{ + return true; +} + +JSObject* XSLTProcessorConstructorImp::construct(ExecState* exec, const List& args) +{ + return new JSXSLTProcessor(XSLTProcessorPrototype::self(exec)); +} + +} // namespace KJS + +#endif // ENABLE(XSLT) diff --git a/WebCore/bindings/js/JSXSLTProcessor.h b/WebCore/bindings/js/JSXSLTProcessor.h new file mode 100644 index 0000000..26ba6b3 --- /dev/null +++ b/WebCore/bindings/js/JSXSLTProcessor.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2005, 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 + * 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 + * 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSXSLTProcessor_h +#define JSXSLTProcessor_h + +#if ENABLE(XSLT) + +#include "kjs_binding.h" + +namespace WebCore { + +class XSLTProcessor; + +// Eventually we should implement XSLTException: +// http://lxr.mozilla.org/seamonkey/source/content/xsl/public/nsIXSLTException.idl +// http://bugs.webkit.org/show_bug.cgi?id=5446 + +class JSXSLTProcessor : public DOMObject { +public: + JSXSLTProcessor(KJS::JSObject* prototype); + ~JSXSLTProcessor(); + + virtual const KJS::ClassInfo* classInfo() const { return &info; } + static const KJS::ClassInfo info; + + XSLTProcessor* impl() const { return m_impl.get(); } + +private: + RefPtr<XSLTProcessor> m_impl; +}; + +class XSLTProcessorConstructorImp : public DOMObject { +public: + XSLTProcessorConstructorImp(KJS::ExecState*); + + virtual bool implementsConstruct() const; + virtual KJS::JSObject* construct(KJS::ExecState*, const KJS::List&); +}; + +KJS::JSValue* jsXSLTProcessorPrototypeFunctionImportStylesheet(KJS::ExecState*, KJS::JSObject*, const KJS::List&); +KJS::JSValue* jsXSLTProcessorPrototypeFunctionTransformToFragment(KJS::ExecState*, KJS::JSObject*, const KJS::List&); +KJS::JSValue* jsXSLTProcessorPrototypeFunctionTransformToDocument(KJS::ExecState*, KJS::JSObject*, const KJS::List&); +KJS::JSValue* jsXSLTProcessorPrototypeFunctionSetParameter(KJS::ExecState*, KJS::JSObject*, const KJS::List&); +KJS::JSValue* jsXSLTProcessorPrototypeFunctionGetParameter(KJS::ExecState*, KJS::JSObject*, const KJS::List&); +KJS::JSValue* jsXSLTProcessorPrototypeFunctionRemoveParameter(KJS::ExecState*, KJS::JSObject*, const KJS::List&); +KJS::JSValue* jsXSLTProcessorPrototypeFunctionClearParameters(KJS::ExecState*, KJS::JSObject*, const KJS::List&); +KJS::JSValue* jsXSLTProcessorPrototypeFunctionReset(KJS::ExecState*, KJS::JSObject*, const KJS::List&); + +} // namespace WebCore + +#endif // ENABLE(XSLT) + +#endif // JSXSLTProcessor_h diff --git a/WebCore/bindings/js/PausedTimeouts.cpp b/WebCore/bindings/js/PausedTimeouts.cpp new file mode 100644 index 0000000..c8a59d8 --- /dev/null +++ b/WebCore/bindings/js/PausedTimeouts.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2000 Harri Porten (porten@kde.org) + * Copyright (C) 2006 Jon Shier (jshier@iastate.edu) + * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reseved. + * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#include "config.h" +#include "PausedTimeouts.h" + +#include "ScheduledAction.h" + +namespace WebCore { + +PausedTimeouts::~PausedTimeouts() +{ + PausedTimeout* array = m_array; + if (!array) + return; + size_t count = m_length; + for (size_t i = 0; i != count; ++i) + delete array[i].action; + delete [] array; +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/PausedTimeouts.h b/WebCore/bindings/js/PausedTimeouts.h new file mode 100644 index 0000000..3839eae --- /dev/null +++ b/WebCore/bindings/js/PausedTimeouts.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2000 Harri Porten (porten@kde.org) + * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reseved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef PausedTimeouts_h +#define PausedTimeouts_h + +#include <wtf/Noncopyable.h> + +namespace WebCore { + + class ScheduledAction; + + struct PausedTimeout { + int timeoutId; + int nestingLevel; + double nextFireInterval; + double repeatInterval; + ScheduledAction* action; + }; + + class PausedTimeouts : Noncopyable { + public: + PausedTimeouts(PausedTimeout* array, size_t length) + : m_array(array) + , m_length(length) + { + } + + ~PausedTimeouts(); + + size_t numTimeouts() const { return m_length; } + PausedTimeout* takeTimeouts() { PausedTimeout* a = m_array; m_array = 0; return a; } + + private: + PausedTimeout* m_array; + size_t m_length; + }; + +} // namespace WebCore + +#endif // PausedTimeouts_h diff --git a/WebCore/bindings/js/ScheduledAction.cpp b/WebCore/bindings/js/ScheduledAction.cpp new file mode 100644 index 0000000..a26923d --- /dev/null +++ b/WebCore/bindings/js/ScheduledAction.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2000 Harri Porten (porten@kde.org) + * Copyright (C) 2006 Jon Shier (jshier@iastate.edu) + * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reseved. + * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#include "config.h" +#include "ScheduledAction.h" + +#include "CString.h" +#include "Chrome.h" +#include "DOMWindow.h" +#include "Document.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "Page.h" +#include "kjs_proxy.h" +#include "kjs_window.h" + +using namespace KJS; + +namespace WebCore { + +ScheduledAction::ScheduledAction(JSValue* func, const List& args) + : m_func(func) +{ + List::const_iterator end = args.end(); + for (List::const_iterator it = args.begin(); it != end; ++it) + m_args.append(*it); +} + + +void ScheduledAction::execute(Window* window) +{ + RefPtr<Frame> frame = window->impl()->frame(); + if (!frame) + return; + + if (!frame->scriptProxy()->isEnabled()) + return; + + KJSProxy* scriptProxy = frame->scriptProxy(); + Window* globalObject = scriptProxy->globalObject(); + + scriptProxy->setProcessingTimerCallback(true); + + if (JSValue* func = m_func.get()) { + JSLock lock; + if (func->isObject() && static_cast<JSObject*>(func)->implementsCall()) { + ExecState* exec = window->globalExec(); + ASSERT(window == globalObject); + + List args; + size_t size = m_args.size(); + for (size_t i = 0; i < size; ++i) + args.append(m_args[i]); + + globalObject->startTimeoutCheck(); + static_cast<JSObject*>(func)->call(exec, window, args); + globalObject->stopTimeoutCheck(); + if (exec->hadException()) { + JSObject* exception = exec->exception()->toObject(exec); + exec->clearException(); + String message = exception->get(exec, exec->propertyNames().message)->toString(exec); + int lineNumber = exception->get(exec, "line")->toInt32(exec); + if (Interpreter::shouldPrintExceptions()) + printf("(timer):%s\n", message.utf8().data()); + if (Page* page = frame->page()) + page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, message, lineNumber, String()); + } + } + } else + frame->loader()->executeScript(m_code); + + // Update our document's rendering following the execution of the timeout callback. + // FIXME: Why not use updateDocumentsRendering to update rendering of all documents? + // FIXME: Is this really the right point to do the update? We need a place that works + // for all possible entry points that might possibly execute script, but this seems + // to be a bit too low-level. + if (Document* doc = frame->document()) + doc->updateRendering(); + + scriptProxy->setProcessingTimerCallback(false); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/ScheduledAction.h b/WebCore/bindings/js/ScheduledAction.h new file mode 100644 index 0000000..a3b1858 --- /dev/null +++ b/WebCore/bindings/js/ScheduledAction.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2000 Harri Porten (porten@kde.org) + * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reseved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef ScheduledAction_h +#define ScheduledAction_h + +#include "PlatformString.h" +#include <kjs/protect.h> +#include <wtf/Vector.h> + +namespace KJS { + class Window; + class JSValue; + class List; +} + +namespace WebCore { + + /** + * An action (either function or string) to be executed after a specified + * time interval, either once or repeatedly. Used for window.setTimeout() + * and window.setInterval() + */ + class ScheduledAction { + public: + ScheduledAction(KJS::JSValue* func, const KJS::List& args); + ScheduledAction(const String& code) + : m_code(code) + { + } + + void execute(KJS::Window*); + + private: + KJS::ProtectedPtr<KJS::JSValue> m_func; + Vector<KJS::ProtectedPtr<KJS::JSValue> > m_args; + String m_code; + }; + +} // namespace WebCore + +#endif // ScheduledAction_h diff --git a/WebCore/bindings/js/kjs_binding.cpp b/WebCore/bindings/js/kjs_binding.cpp new file mode 100644 index 0000000..5855ca0 --- /dev/null +++ b/WebCore/bindings/js/kjs_binding.cpp @@ -0,0 +1,378 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +// gcc 3.x can't handle including the HashMap pointer specialization in this file +#if defined __GNUC__ && !defined __GLIBCXX__ // less than gcc 3.4 +#define HASH_MAP_PTR_SPEC_WORKAROUND 1 +#endif + +#include "config.h" +#include "kjs_binding.h" + +#include "DOMCoreException.h" +#include "EventException.h" +#include "ExceptionCode.h" +#include "HTMLImageElement.h" +#include "HTMLNames.h" +#include "JSDOMCoreException.h" +#include "JSEventException.h" +#include "JSNode.h" +#include "JSRangeException.h" +#include "JSXMLHttpRequestException.h" +#include "KURL.h" +#include "RangeException.h" +#include "XMLHttpRequestException.h" +#include "kjs_window.h" + +#if ENABLE(SVG) +#include "JSSVGException.h" +#include "SVGException.h" +#endif + +#if ENABLE(XPATH) +#include "JSXPathException.h" +#include "XPathException.h" +#endif + +using namespace KJS; + +namespace WebCore { + +using namespace HTMLNames; + +typedef HashMap<void*, DOMObject*> DOMObjectMap; +typedef HashMap<WebCore::Node*, JSNode*> NodeMap; +typedef HashMap<Document*, NodeMap*> NodePerDocMap; + +// For debugging, keep a set of wrappers currently registered, and check that +// all are unregistered before they are destroyed. This has helped us fix at +// least one bug. + +static void addWrapper(DOMObject* wrapper); +static void removeWrapper(DOMObject* wrapper); +static void removeWrappers(const NodeMap& wrappers); + +#ifdef NDEBUG + +static inline void addWrapper(DOMObject*) +{ +} + +static inline void removeWrapper(DOMObject*) +{ +} + +static inline void removeWrappers(const NodeMap&) +{ +} + +#else + +static HashSet<DOMObject*>& wrapperSet() +{ + static HashSet<DOMObject*> staticWrapperSet; + return staticWrapperSet; +} + +static void addWrapper(DOMObject* wrapper) +{ + ASSERT(!wrapperSet().contains(wrapper)); + wrapperSet().add(wrapper); +} + +static void removeWrapper(DOMObject* wrapper) +{ + if (!wrapper) + return; + ASSERT(wrapperSet().contains(wrapper)); + wrapperSet().remove(wrapper); +} + +static void removeWrappers(const NodeMap& wrappers) +{ + for (NodeMap::const_iterator it = wrappers.begin(); it != wrappers.end(); ++it) + removeWrapper(it->second); +} + +DOMObject::~DOMObject() +{ + ASSERT(!wrapperSet().contains(this)); +} + +#endif + +static DOMObjectMap& domObjects() +{ + // Don't use malloc here. Calling malloc from a mark function can deadlock. + static DOMObjectMap staticDOMObjects; + return staticDOMObjects; +} + +static NodePerDocMap& domNodesPerDocument() +{ + // domNodesPerDocument() callers must synchronize using the JSLock because + // domNodesPerDocument() is called from a mark function, which can run + // on a secondary thread. + ASSERT(JSLock::lockCount()); + + // Don't use malloc here. Calling malloc from a mark function can deadlock. + static NodePerDocMap staticDOMNodesPerDocument; + return staticDOMNodesPerDocument; +} + +DOMObject* ScriptInterpreter::getDOMObject(void* objectHandle) +{ + return domObjects().get(objectHandle); +} + +void ScriptInterpreter::putDOMObject(void* objectHandle, DOMObject* wrapper) +{ + addWrapper(wrapper); + domObjects().set(objectHandle, wrapper); +} + +void ScriptInterpreter::forgetDOMObject(void* objectHandle) +{ + removeWrapper(domObjects().take(objectHandle)); +} + +JSNode* ScriptInterpreter::getDOMNodeForDocument(Document* document, WebCore::Node* node) +{ + if (!document) + return static_cast<JSNode*>(domObjects().get(node)); + NodeMap* documentDict = domNodesPerDocument().get(document); + if (documentDict) + return documentDict->get(node); + return NULL; +} + +void ScriptInterpreter::forgetDOMNodeForDocument(Document* document, WebCore::Node* node) +{ + if (!document) { + removeWrapper(domObjects().take(node)); + return; + } + NodeMap* documentDict = domNodesPerDocument().get(document); + if (documentDict) + removeWrapper(documentDict->take(node)); +} + +void ScriptInterpreter::putDOMNodeForDocument(Document* document, WebCore::Node* node, JSNode* wrapper) +{ + addWrapper(wrapper); + if (!document) { + domObjects().set(node, wrapper); + return; + } + NodeMap* documentDict = domNodesPerDocument().get(document); + if (!documentDict) { + documentDict = new NodeMap; + domNodesPerDocument().set(document, documentDict); + } + documentDict->set(node, wrapper); +} + +void ScriptInterpreter::forgetAllDOMNodesForDocument(Document* document) +{ + ASSERT(document); + NodeMap* map = domNodesPerDocument().take(document); + if (!map) + return; + removeWrappers(*map); + delete map; +} + +void ScriptInterpreter::markDOMNodesForDocument(Document* doc) +{ + NodePerDocMap::iterator dictIt = domNodesPerDocument().find(doc); + if (dictIt != domNodesPerDocument().end()) { + NodeMap* nodeDict = dictIt->second; + NodeMap::iterator nodeEnd = nodeDict->end(); + for (NodeMap::iterator nodeIt = nodeDict->begin(); nodeIt != nodeEnd; ++nodeIt) { + JSNode* jsNode = nodeIt->second; + WebCore::Node* node = jsNode->impl(); + + // don't mark wrappers for nodes that are no longer in the + // document - they should not be saved if the node is not + // otherwise reachable from JS. + // However, image elements that aren't in the document are also + // marked, if they are not done loading yet. + if (!jsNode->marked() && (node->inDocument() || (node->hasTagName(imgTag) && + !static_cast<HTMLImageElement*>(node)->haveFiredLoadEvent()))) + jsNode->mark(); + } + } +} + +void ScriptInterpreter::updateDOMNodeDocument(WebCore::Node* node, Document* oldDoc, Document* newDoc) +{ + ASSERT(oldDoc != newDoc); + JSNode* wrapper = getDOMNodeForDocument(oldDoc, node); + if (wrapper) { + removeWrapper(wrapper); + putDOMNodeForDocument(newDoc, node, wrapper); + forgetDOMNodeForDocument(oldDoc, node); + addWrapper(wrapper); + } +} + +JSValue* jsStringOrNull(const String& s) +{ + if (s.isNull()) + return jsNull(); + return jsString(s); +} + +JSValue* jsOwnedStringOrNull(const KJS::UString& s) +{ + if (s.isNull()) + return jsNull(); + return jsOwnedString(s); +} + +JSValue* jsStringOrUndefined(const String& s) +{ + if (s.isNull()) + return jsUndefined(); + return jsString(s); +} + +JSValue* jsStringOrFalse(const String& s) +{ + if (s.isNull()) + return jsBoolean(false); + return jsString(s); +} + +JSValue* jsStringOrNull(const KURL& url) +{ + if (url.isNull()) + return jsNull(); + return jsString(url.string()); +} + +JSValue* jsStringOrUndefined(const KURL& url) +{ + if (url.isNull()) + return jsUndefined(); + return jsString(url.string()); +} + +JSValue* jsStringOrFalse(const KURL& url) +{ + if (url.isNull()) + return jsBoolean(false); + return jsString(url.string()); +} + +String valueToStringWithNullCheck(ExecState* exec, JSValue* val) +{ + if (val->isNull()) + return String(); + return val->toString(exec); +} + +String valueToStringWithUndefinedOrNullCheck(ExecState* exec, JSValue* val) +{ + if (val->isUndefinedOrNull()) + return String(); + return val->toString(exec); +} + +void setDOMException(ExecState* exec, ExceptionCode ec) +{ + if (!ec || exec->hadException()) + return; + + // To be removed: See XMLHttpRequest.h. + if (ec == XMLHttpRequestException::PERMISSION_DENIED) { + throwError(exec, GeneralError, "Permission denied"); + return; + } + + ExceptionCodeDescription description; + getExceptionCodeDescription(ec, description); + + JSValue* errorObject = 0; + switch (description.type) { + case DOMExceptionType: + errorObject = toJS(exec, new DOMCoreException(description)); + break; + case RangeExceptionType: + errorObject = toJS(exec, new RangeException(description)); + break; + case EventExceptionType: + errorObject = toJS(exec, new EventException(description)); + break; + case XMLHttpRequestExceptionType: + errorObject = toJS(exec, new XMLHttpRequestException(description)); + break; +#if ENABLE(SVG) + case SVGExceptionType: + errorObject = toJS(exec, new SVGException(description), 0); + break; +#endif +#if ENABLE(XPATH) + case XPathExceptionType: + errorObject = toJS(exec, new XPathException(description)); + break; +#endif + } + + ASSERT(errorObject); + exec->setException(errorObject); +} + +bool allowsAccessFromFrame(ExecState* exec, Frame* frame) +{ + if (!frame) + return false; + Window* window = Window::retrieveWindow(frame); + return window && window->allowsAccessFrom(exec); +} + +bool allowsAccessFromFrame(ExecState* exec, Frame* frame, String& message) +{ + if (!frame) + return false; + Window* window = Window::retrieveWindow(frame); + return window && window->allowsAccessFrom(exec, message); +} + +void printErrorMessageForFrame(Frame* frame, const String& message) +{ + if (!frame) + return; + if (Window* window = Window::retrieveWindow(frame)) + window->printErrorMessage(message); +} + +JSValue* nonCachingStaticFunctionGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot) +{ + const HashEntry* entry = slot.staticEntry(); + return new PrototypeFunction(exec, entry->params, propertyName, entry->value.functionValue); +} + +JSValue* objectToStringFunctionGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot&) +{ + return new PrototypeFunction(exec, 0, propertyName, objectProtoFuncToString); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/kjs_binding.h b/WebCore/bindings/js/kjs_binding.h new file mode 100644 index 0000000..fb95652 --- /dev/null +++ b/WebCore/bindings/js/kjs_binding.h @@ -0,0 +1,152 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef kjs_binding_h +#define kjs_binding_h + +#include <kjs/function.h> +#include <kjs/interpreter.h> +#include <kjs/lookup.h> +#include <wtf/Noncopyable.h> + +#if PLATFORM(MAC) +#include <JavaScriptCore/runtime.h> +#endif + +namespace WebCore { + + class AtomicString; + class Document; + class Event; + class Frame; + class KURL; + class Node; + class String; + class JSNode; + + typedef int ExceptionCode; + +#if ENABLE(SVG) + class SVGElement; +#endif + + // Base class for all objects in this binding except Window. + class DOMObject : public KJS::JSObject { + protected: + explicit DOMObject(KJS::JSValue* prototype) // FIXME: this should take a JSObject once JSLocation has a real prototype + : JSObject(prototype) + { + // DOMObject destruction is not thread-safe because DOMObjects wrap + // unsafe WebCore DOM data structures. + KJS::Collector::collectOnMainThreadOnly(this); + } + +#ifndef NDEBUG + virtual ~DOMObject(); +#endif + + private: + DOMObject(); + }; + + class ScriptInterpreter : public KJS::Interpreter { + public: + static DOMObject* getDOMObject(void* objectHandle); + static void putDOMObject(void* objectHandle, DOMObject*); + static void forgetDOMObject(void* objectHandle); + + static JSNode* getDOMNodeForDocument(Document*, Node*); + static void putDOMNodeForDocument(Document*, Node*, JSNode* nodeWrapper); + static void forgetDOMNodeForDocument(Document*, Node*); + static void forgetAllDOMNodesForDocument(Document*); + static void updateDOMNodeDocument(Node*, Document* oldDoc, Document* newDoc); + static void markDOMNodesForDocument(Document*); + }; + + // Retrieve from cache, or create, a JS wrapper for a DOM object. + template<class DOMObj, class JSDOMObj, class JSDOMObjPrototype> inline KJS::JSValue* cacheDOMObject(KJS::ExecState* exec, DOMObj* domObj) + { + if (!domObj) + return KJS::jsNull(); + if (DOMObject* ret = ScriptInterpreter::getDOMObject(domObj)) + return ret; + DOMObject* ret = new JSDOMObj(JSDOMObjPrototype::self(exec), domObj); + ScriptInterpreter::putDOMObject(domObj, ret); + return ret; + } + +#if ENABLE(SVG) + // Retrieve from cache, or create, a JS wrapper for an SVG DOM object. + template<class DOMObj, class JSDOMObj, class JSDOMObjPrototype> inline KJS::JSValue* cacheSVGDOMObject(KJS::ExecState* exec, DOMObj* domObj, SVGElement* context) + { + if (!domObj) + return KJS::jsNull(); + if (DOMObject* ret = ScriptInterpreter::getDOMObject(domObj)) + return ret; + DOMObject* ret = new JSDOMObj(JSDOMObjPrototype::self(exec), domObj, context); + ScriptInterpreter::putDOMObject(domObj, ret); + return ret; + } +#endif + + // Convert a DOM implementation exception code into a JavaScript exception in the execution state. + void setDOMException(KJS::ExecState*, ExceptionCode); + + // Helper class to call setDOMException on exit without adding lots of separate calls to that function. + class DOMExceptionTranslator : Noncopyable { + public: + explicit DOMExceptionTranslator(KJS::ExecState* exec) : m_exec(exec), m_code(0) { } + ~DOMExceptionTranslator() { setDOMException(m_exec, m_code); } + operator ExceptionCode&() { return m_code; } + private: + KJS::ExecState* m_exec; + ExceptionCode m_code; + }; + + KJS::JSValue* jsStringOrNull(const String&); // null if the string is null + KJS::JSValue* jsStringOrNull(const KURL&); // null if the URL is null + + KJS::JSValue* jsStringOrUndefined(const String&); // undefined if the string is null + KJS::JSValue* jsStringOrUndefined(const KURL&); // undefined if the URL is null + + KJS::JSValue* jsStringOrFalse(const String&); // boolean false if the string is null + KJS::JSValue* jsStringOrFalse(const KURL&); // boolean false if the URL is null + + // See JavaScriptCore for explanation: Should be used for any UString that is already owned by another + // object, to let the engine know that collecting the JSString wrapper is unlikely to save memory. + KJS::JSValue* jsOwnedStringOrNull(const KJS::UString&); + + String valueToStringWithNullCheck(KJS::ExecState*, KJS::JSValue*); // null String if the value is null + String valueToStringWithUndefinedOrNullCheck(KJS::ExecState*, KJS::JSValue*); // null String if the value is null or undefined + + template <typename T> inline KJS::JSValue* toJS(KJS::ExecState* exec, PassRefPtr<T> ptr) { return toJS(exec, ptr.get()); } + + // Helpers for Window, History, and Location classes to implement cross-domain policy. + // Besides the cross-domain check, they need non-caching versions of staticFunctionGetter for + // because we do not want current property values involved at all. + bool allowsAccessFromFrame(KJS::ExecState*, Frame*); + bool allowsAccessFromFrame(KJS::ExecState*, Frame*, String& message); + void printErrorMessageForFrame(Frame*, const String& message); + KJS::JSValue* nonCachingStaticFunctionGetter(KJS::ExecState*, KJS::JSObject*, const KJS::Identifier& propertyName, const KJS::PropertySlot&); + KJS::JSValue* objectToStringFunctionGetter(KJS::ExecState*, KJS::JSObject*, const KJS::Identifier& propertyName, const KJS::PropertySlot&); + +} // namespace WebCore + +#endif // kjs_binding_h diff --git a/WebCore/bindings/js/kjs_css.cpp b/WebCore/bindings/js/kjs_css.cpp new file mode 100644 index 0000000..e2ab70d --- /dev/null +++ b/WebCore/bindings/js/kjs_css.cpp @@ -0,0 +1,85 @@ +// -*- c-basic-offset: 2 -*- +/* + * Copyright (C) 2000 Harri Porten (porten@kde.org) + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006 James G. Speth (speth@end.com) + * Copyright (C) 2006 Samuel Weinig (sam@webkit.org) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "kjs_css.h" + +#include "CSSPrimitiveValue.h" +#include "JSCSSPrimitiveValue.h" +#include "kjs_dom.h" + +#include "kjs_css.lut.h" + +namespace WebCore { + +using namespace KJS; + +const ClassInfo JSRGBColor::info = { "RGBColor", 0, &JSRGBColorTable }; + +/* +@begin JSRGBColorTable 3 + red WebCore::JSRGBColor::Red DontDelete|ReadOnly + green WebCore::JSRGBColor::Green DontDelete|ReadOnly + blue WebCore::JSRGBColor::Blue DontDelete|ReadOnly +@end +*/ + +JSRGBColor::JSRGBColor(JSObject* prototype, unsigned color) + : DOMObject(prototype) + , m_color(color) +{ +} + +JSRGBColor::~JSRGBColor() +{ +} + +bool JSRGBColor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + return getStaticValueSlot<JSRGBColor, DOMObject>(exec, &JSRGBColorTable, this, propertyName, slot); +} + +JSValue* JSRGBColor::getValueProperty(ExecState* exec, int token) const +{ + int color = m_color; + switch (token) { + case Red: + color >>= 8; + // fall through + case Green: + color >>= 8; + // fall through + case Blue: + return toJS(exec, new CSSPrimitiveValue(color & 0xFF, CSSPrimitiveValue::CSS_NUMBER)); + default: + return 0; + } +} + +JSValue* getJSRGBColor(ExecState* exec, unsigned color) +{ + // FIXME: implement equals for RGBColor since they're not refcounted objects + return new JSRGBColor(exec->lexicalGlobalObject()->objectPrototype(), color); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/kjs_css.h b/WebCore/bindings/js/kjs_css.h new file mode 100644 index 0000000..5a42e0c --- /dev/null +++ b/WebCore/bindings/js/kjs_css.h @@ -0,0 +1,55 @@ + // -*- c-basic-offset: 2 -*- +/* + * This file is part of the KDE libraries + * Copyright (C) 2000 Harri Porten (porten@kde.org) + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef kjs_css_h +#define kjs_css_h + +#include "Color.h" +#include "kjs_binding.h" + +namespace WebCore { + + class JSRGBColor : public DOMObject { + public: + JSRGBColor(KJS::JSObject* prototype, unsigned color); + ~JSRGBColor(); + + virtual bool getOwnPropertySlot(KJS::ExecState*, const KJS::Identifier&, KJS::PropertySlot&); + KJS::JSValue* getValueProperty(KJS::ExecState*, int token) const; + // no put - all read-only + + virtual const KJS::ClassInfo* classInfo() const { return &info; } + static const KJS::ClassInfo info; + + enum { Red, Green, Blue }; + + unsigned impl() const { return m_color; } + + private: + unsigned m_color; + }; + + KJS::JSValue* getJSRGBColor(KJS::ExecState*, unsigned color); + +} // namespace WebCore + +#endif // kjs_css_h diff --git a/WebCore/bindings/js/kjs_dom.cpp b/WebCore/bindings/js/kjs_dom.cpp new file mode 100644 index 0000000..e718d41 --- /dev/null +++ b/WebCore/bindings/js/kjs_dom.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2000 Harri Porten (porten@kde.org) + * Copyright (C) 2006 Jon Shier (jshier@iastate.edu) + * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "kjs_dom.h" + +#include "Document.h" +#include "EventTarget.h" +#include "Frame.h" +#include "HTMLNames.h" +#include "HTMLPlugInElement.h" +#include "JSAttr.h" +#include "JSNode.h" +#include "XMLHttpRequest.h" +#include "kjs_events.h" +#include "kjs_window.h" + +#if ENABLE(SVG) +#include "JSSVGElementInstance.h" +#endif + +#if USE(JAVASCRIPTCORE_BINDINGS) +#include <bindings/runtime_object.h> +#endif + +namespace WebCore { + +using namespace KJS; +using namespace HTMLNames; + +Attr* toAttr(JSValue* val, bool& ok) +{ + if (!val || !val->isObject(&JSAttr::info)) { + ok = false; + return 0; + } + + ok = true; + return static_cast<Attr*>(static_cast<JSNode*>(val)->impl()); +} + +bool checkNodeSecurity(ExecState* exec, Node* node) +{ + return node && allowsAccessFromFrame(exec, node->document()->frame()); +} + +JSValue* toJS(ExecState* exec, EventTarget* target) +{ + if (!target) + return jsNull(); + +#if ENABLE(SVG) + // SVGElementInstance supports both toSVGElementInstance and toNode since so much mouse handling code depends on toNode returning a valid node. + SVGElementInstance* instance = target->toSVGElementInstance(); + if (instance) + return toJS(exec, instance); +#endif + + Node* node = target->toNode(); + if (node) + return toJS(exec, node); + + if (XMLHttpRequest* xhr = target->toXMLHttpRequest()) + // XMLHttpRequest is always created via JS, so we don't need to use cacheDOMObject() here. + return ScriptInterpreter::getDOMObject(xhr); + + // There are two kinds of EventTargets: EventTargetNode and XMLHttpRequest. + // If SVG support is enabled, there is also SVGElementInstance. + ASSERT(0); + return jsNull(); +} + +JSObject* getRuntimeObject(ExecState* exec, Node* n) +{ + if (!n) + return 0; + +#if USE(JAVASCRIPTCORE_BINDINGS) + if (n->hasTagName(objectTag) || n->hasTagName(embedTag) || n->hasTagName(appletTag)) { + HTMLPlugInElement* plugInElement = static_cast<HTMLPlugInElement*>(n); + if (plugInElement->getInstance() && plugInElement->getInstance()->rootObject()) + // The instance is owned by the PlugIn element. + return KJS::Bindings::Instance::createRuntimeObject(plugInElement->getInstance()); + } +#endif + + // If we don't have a runtime object return 0. + return 0; +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/kjs_dom.h b/WebCore/bindings/js/kjs_dom.h new file mode 100644 index 0000000..6e0f136 --- /dev/null +++ b/WebCore/bindings/js/kjs_dom.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2000 Harri Porten (porten@kde.org) + * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef kjs_dom_h +#define kjs_dom_h + +#include "JSNode.h" +#include "Node.h" +#include "kjs_binding.h" + +namespace WebCore { + + class Attr; + class EventTarget; + + Attr* toAttr(KJS::JSValue*, bool& ok); + + bool checkNodeSecurity(KJS::ExecState*, Node*); + KJS::JSObject* getRuntimeObject(KJS::ExecState*, Node*); + KJS::JSValue* toJS(KJS::ExecState*, EventTarget*); + KJS::JSObject* getNodeConstructor(KJS::ExecState*); + +} // namespace WebCore + +#endif // kjs_dom_h diff --git a/WebCore/bindings/js/kjs_events.cpp b/WebCore/bindings/js/kjs_events.cpp new file mode 100644 index 0000000..f289209 --- /dev/null +++ b/WebCore/bindings/js/kjs_events.cpp @@ -0,0 +1,518 @@ +/* + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "kjs_events.h" + +#include "CString.h" +#include "Chrome.h" +#include "Clipboard.h" +#include "ClipboardEvent.h" +#include "DOMWindow.h" +#include "Document.h" +#include "Event.h" +#include "EventNames.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "HTMLImageElement.h" +#include "HTMLNames.h" +#include "JSEvent.h" +#include "JSEventTargetNode.h" +#include "Page.h" +#include "kjs_proxy.h" +#include "kjs_window.h" +#include <kjs/array_object.h> +#include <kjs/function_object.h> + +#include "kjs_events.lut.h" + +namespace WebCore { + +using namespace KJS; +using namespace EventNames; +using namespace HTMLNames; + +JSAbstractEventListener::JSAbstractEventListener(bool html) + : m_html(html) +{ +} + +void JSAbstractEventListener::handleEvent(Event* ele, bool isWindowEvent) +{ +#ifdef KJS_DEBUGGER + if (KJSDebugWin::instance() && KJSDebugWin::instance()->inSession()) + return; +#endif + + Event* event = ele; + + JSObject* listener = listenerObj(); + if (!listener) + return; + + KJS::Window* window = windowObj(); + // Null check as clearWindowObj() can clear this and we still get called back by + // xmlhttprequest objects. See http://bugs.webkit.org/show_bug.cgi?id=13275 + if (!window) + return; + Frame *frame = window->impl()->frame(); + if (!frame) + return; + if (!frame->scriptProxy()->isEnabled()) + return; + + JSLock lock; + + JSGlobalObject* globalObject = frame->scriptProxy()->globalObject(); + ExecState* exec = globalObject->globalExec(); + + JSValue* handleEventFuncValue = listener->get(exec, "handleEvent"); + JSObject* handleEventFunc = 0; + if (handleEventFuncValue->isObject()) { + handleEventFunc = static_cast<JSObject*>(handleEventFuncValue); + if (!handleEventFunc->implementsCall()) + handleEventFunc = 0; + } + + if (handleEventFunc || listener->implementsCall()) { + ref(); + + List args; + args.append(toJS(exec, event)); + + window->setCurrentEvent(event); + + JSValue* retval; + if (handleEventFunc) { + globalObject->startTimeoutCheck(); + retval = handleEventFunc->call(exec, listener, args); + } else { + JSObject* thisObj; + if (isWindowEvent) + thisObj = window; + else + thisObj = static_cast<JSObject*>(toJS(exec, event->currentTarget())); + globalObject->startTimeoutCheck(); + retval = listener->call(exec, thisObj, args); + } + globalObject->stopTimeoutCheck(); + + window->setCurrentEvent(0); + + if (exec->hadException()) { + JSObject* exception = exec->exception()->toObject(exec); + String message = exception->get(exec, exec->propertyNames().message)->toString(exec); + int lineNumber = exception->get(exec, "line")->toInt32(exec); + String sourceURL = exception->get(exec, "sourceURL")->toString(exec); + if (Interpreter::shouldPrintExceptions()) + printf("(event handler):%s\n", message.utf8().data()); + if (Page* page = frame->page()) + page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, message, lineNumber, sourceURL); + exec->clearException(); + } else { + if (!retval->isUndefinedOrNull() && event->storesResultAsString()) + event->storeResult(retval->toString(exec)); + if (m_html) { + bool retvalbool; + if (retval->getBoolean(retvalbool) && !retvalbool) + event->preventDefault(); + } + } + + Document::updateDocumentsRendering(); + deref(); + } +} + +bool JSAbstractEventListener::isHTMLEventListener() const +{ + return m_html; +} + +// ------------------------------------------------------------------------- + +JSUnprotectedEventListener::JSUnprotectedEventListener(JSObject* listener, KJS::Window* win, bool html) + : JSAbstractEventListener(html) + , m_listener(listener) + , m_win(win) +{ + if (m_listener) { + KJS::Window::UnprotectedListenersMap& listeners = html + ? m_win->jsUnprotectedHTMLEventListeners() : m_win->jsUnprotectedEventListeners(); + listeners.set(m_listener, this); + } +} + +JSUnprotectedEventListener::~JSUnprotectedEventListener() +{ + if (m_listener && m_win) { + KJS::Window::UnprotectedListenersMap& listeners = isHTMLEventListener() + ? m_win->jsUnprotectedHTMLEventListeners() : m_win->jsUnprotectedEventListeners(); + listeners.remove(m_listener); + } +} + +JSObject* JSUnprotectedEventListener::listenerObj() const +{ + return m_listener; +} + +KJS::Window* JSUnprotectedEventListener::windowObj() const +{ + return m_win; +} + +void JSUnprotectedEventListener::clearWindowObj() +{ + m_win = 0; +} + +void JSUnprotectedEventListener::mark() +{ + if (m_listener && !m_listener->marked()) + m_listener->mark(); +} + +#ifndef NDEBUG +#ifndef LOG_CHANNEL_PREFIX +#define LOG_CHANNEL_PREFIX Log +#endif +WTFLogChannel LogWebCoreEventListenerLeaks = { 0x00000000, "", WTFLogChannelOn }; + +struct EventListenerCounter { + static unsigned count; + ~EventListenerCounter() + { + if (count) + LOG(WebCoreEventListenerLeaks, "LEAK: %u EventListeners\n", count); + } +}; +unsigned EventListenerCounter::count = 0; +static EventListenerCounter eventListenerCounter; +#endif + +// ------------------------------------------------------------------------- + +JSEventListener::JSEventListener(JSObject* listener, KJS::Window* win, bool html) + : JSAbstractEventListener(html) + , m_listener(listener) + , m_win(win) +{ + if (m_listener) { + KJS::Window::ListenersMap& listeners = html + ? m_win->jsHTMLEventListeners() : m_win->jsEventListeners(); + listeners.set(m_listener, this); + } +#ifndef NDEBUG + ++eventListenerCounter.count; +#endif +} + +JSEventListener::~JSEventListener() +{ + if (m_listener && m_win) { + KJS::Window::ListenersMap& listeners = isHTMLEventListener() + ? m_win->jsHTMLEventListeners() : m_win->jsEventListeners(); + listeners.remove(m_listener); + } +#ifndef NDEBUG + --eventListenerCounter.count; +#endif +} + +JSObject* JSEventListener::listenerObj() const +{ + return m_listener; +} + +KJS::Window* JSEventListener::windowObj() const +{ + return m_win; +} + +void JSEventListener::clearWindowObj() +{ + m_win = 0; +} + +// ------------------------------------------------------------------------- + +JSLazyEventListener::JSLazyEventListener(const String& functionName, const String& code, KJS::Window* win, Node* node, int lineNumber) + : JSEventListener(0, win, true) + , m_functionName(functionName) + , m_code(code) + , m_parsed(false) + , m_lineNumber(lineNumber) + , m_originalNode(node) +{ + // We don't retain the original node because we assume it + // will stay alive as long as this handler object is around + // and we need to avoid a reference cycle. If JS transfers + // this handler to another node, parseCode will be called and + // then originalNode is no longer needed. +} + +JSObject* JSLazyEventListener::listenerObj() const +{ + parseCode(); + return m_listener; +} + +JSValue* JSLazyEventListener::eventParameterName() const +{ + static ProtectedPtr<JSValue> eventString = jsString("event"); + return eventString.get(); +} + +void JSLazyEventListener::parseCode() const +{ + if (m_parsed) + return; + m_parsed = true; + + Frame* frame = windowObj()->impl()->frame(); + if (frame && frame->scriptProxy()->isEnabled()) { + ExecState* exec = frame->scriptProxy()->globalObject()->globalExec(); + + JSLock lock; + JSObject* constr = frame->scriptProxy()->globalObject()->functionConstructor(); + List args; + + UString sourceURL(frame->loader()->url().string()); + args.append(eventParameterName()); + args.append(jsString(m_code)); + m_listener = constr->construct(exec, args, m_functionName, sourceURL, m_lineNumber); // FIXME: is globalExec ok ? + + FunctionImp* listenerAsFunction = static_cast<FunctionImp*>(m_listener.get()); + + if (exec->hadException()) { + exec->clearException(); + + // failed to parse, so let's just make this listener a no-op + m_listener = 0; + } else if (m_originalNode) { + // Add the event's home element to the scope + // (and the document, and the form - see JSHTMLElement::eventHandlerScope) + ScopeChain scope = listenerAsFunction->scope(); + + JSValue* thisObj = toJS(exec, m_originalNode); + if (thisObj->isObject()) { + static_cast<JSEventTargetNode*>(thisObj)->pushEventHandlerScope(exec, scope); + listenerAsFunction->setScope(scope); + } + } + } + + // no more need to keep the unparsed code around + m_functionName = String(); + m_code = String(); + + if (m_listener) { + KJS::Window::ListenersMap& listeners = isHTMLEventListener() + ? windowObj()->jsHTMLEventListeners() : windowObj()->jsEventListeners(); + listeners.set(m_listener, const_cast<JSLazyEventListener*>(this)); + } +} + +JSValue* getNodeEventListener(EventTargetNode* n, const AtomicString& eventType) +{ + if (JSAbstractEventListener* listener = static_cast<JSAbstractEventListener*>(n->getHTMLEventListener(eventType))) { + if (JSValue* obj = listener->listenerObj()) + return obj; + } + return jsNull(); +} + +// ------------------------------------------------------------------------- + +const ClassInfo JSClipboard::info = { "Clipboard", 0, &JSClipboardTable }; + +/* Source for JSClipboardTable. Use "make hashtables" to regenerate. +@begin JSClipboardTable 3 + dropEffect WebCore::JSClipboard::DropEffect DontDelete + effectAllowed WebCore::JSClipboard::EffectAllowed DontDelete + types WebCore::JSClipboard::Types DontDelete|ReadOnly +@end +@begin JSClipboardPrototypeTable 4 + clearData WebCore::jsClipboardPrototypeFunctionClearData DontDelete|Function 0 + getData WebCore::jsClipboardPrototypeFunctionGetData DontDelete|Function 1 + setData WebCore::jsClipboardPrototypeFunctionSetData DontDelete|Function 2 + setDragImage WebCore::jsClipboardPrototypeFunctionSetDragImage DontDelete|Function 3 +@end +*/ + +KJS_DEFINE_PROTOTYPE(JSClipboardPrototype) +KJS_IMPLEMENT_PROTOTYPE("Clipboard", JSClipboardPrototype) + +JSClipboard::JSClipboard(JSObject* prototype, Clipboard* clipboard) + : DOMObject(prototype) + , m_impl(clipboard) +{ +} + +JSClipboard::~JSClipboard() +{ + ScriptInterpreter::forgetDOMObject(m_impl.get()); +} + +bool JSClipboard::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + return getStaticValueSlot<JSClipboard, DOMObject>(exec, &JSClipboardTable, this, propertyName, slot); +} + +JSValue* JSClipboard::getValueProperty(ExecState* exec, int token) const +{ + Clipboard* clipboard = impl(); + switch (token) { + case DropEffect: + ASSERT(clipboard->isForDragging() || clipboard->dropEffect().isNull()); + return jsStringOrUndefined(clipboard->dropEffect()); + case EffectAllowed: + ASSERT(clipboard->isForDragging() || clipboard->effectAllowed().isNull()); + return jsStringOrUndefined(clipboard->effectAllowed()); + case Types: + { + HashSet<String> types = clipboard->types(); + if (types.isEmpty()) + return jsNull(); + else { + List list; + HashSet<String>::const_iterator end = types.end(); + for (HashSet<String>::const_iterator it = types.begin(); it != end; ++it) + list.append(jsString(UString(*it))); + return exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, list); + } + } + default: + return 0; + } +} + +void JSClipboard::put(ExecState* exec, const Identifier& propertyName, JSValue* value) +{ + lookupPut<JSClipboard, DOMObject>(exec, propertyName, value, &JSClipboardTable, this); +} + +void JSClipboard::putValueProperty(ExecState* exec, int token, JSValue* value) +{ + Clipboard* clipboard = impl(); + switch (token) { + case DropEffect: + // can never set this when not for dragging, thus getting always returns NULL string + if (clipboard->isForDragging()) + clipboard->setDropEffect(value->toString(exec)); + break; + case EffectAllowed: + // can never set this when not for dragging, thus getting always returns NULL string + if (clipboard->isForDragging()) + clipboard->setEffectAllowed(value->toString(exec)); + break; + } +} + +JSValue* jsClipboardPrototypeFunctionClearData(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSClipboard::info)) + return throwError(exec, TypeError); + + Clipboard* clipboard = static_cast<JSClipboard*>(thisObj)->impl(); + + if (args.size() == 0) { + clipboard->clearAllData(); + return jsUndefined(); + } else if (args.size() == 1) { + clipboard->clearData(args[0]->toString(exec)); + return jsUndefined(); + } else + return throwError(exec, SyntaxError, "clearData: Invalid number of arguments"); +} + +JSValue* jsClipboardPrototypeFunctionGetData(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSClipboard::info)) + return throwError(exec, TypeError); + + Clipboard* clipboard = static_cast<JSClipboard*>(thisObj)->impl(); + + if (args.size() == 1) { + bool success; + String result = clipboard->getData(args[0]->toString(exec), success); + if (success) + return jsString(result); + return jsUndefined(); + } else + return throwError(exec, SyntaxError, "getData: Invalid number of arguments"); +} + +JSValue* jsClipboardPrototypeFunctionSetData(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSClipboard::info)) + return throwError(exec, TypeError); + + Clipboard* clipboard = static_cast<JSClipboard*>(thisObj)->impl(); + + if (args.size() == 2) + return jsBoolean(clipboard->setData(args[0]->toString(exec), args[1]->toString(exec))); + return throwError(exec, SyntaxError, "setData: Invalid number of arguments"); +} + +JSValue* jsClipboardPrototypeFunctionSetDragImage(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&JSClipboard::info)) + return throwError(exec, TypeError); + + Clipboard* clipboard = static_cast<JSClipboard*>(thisObj)->impl(); + + if (!clipboard->isForDragging()) + return jsUndefined(); + + if (args.size() != 3) + return throwError(exec, SyntaxError, "setDragImage: Invalid number of arguments"); + + int x = args[1]->toInt32(exec); + int y = args[2]->toInt32(exec); + + // See if they passed us a node + Node* node = toNode(args[0]); + if (!node) + return throwError(exec, TypeError); + + if (!node->isElementNode()) + return throwError(exec, SyntaxError, "setDragImageFromElement: Invalid first argument"); + + if (static_cast<Element*>(node)->hasLocalName(imgTag) && + !node->inDocument()) + clipboard->setDragImage(static_cast<HTMLImageElement*>(node)->cachedImage(), IntPoint(x, y)); + else + clipboard->setDragImageElement(node, IntPoint(x, y)); + + return jsUndefined(); +} + +JSValue* toJS(ExecState* exec, Clipboard* obj) +{ + return cacheDOMObject<Clipboard, JSClipboard, JSClipboardPrototype>(exec, obj); +} + +Clipboard* toClipboard(JSValue* val) +{ + return val->isObject(&JSClipboard::info) ? static_cast<JSClipboard*>(val)->impl() : 0; +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/kjs_events.h b/WebCore/bindings/js/kjs_events.h new file mode 100644 index 0000000..b488cc4 --- /dev/null +++ b/WebCore/bindings/js/kjs_events.h @@ -0,0 +1,132 @@ +/* + * This file is part of the KDE libraries + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * Copyright (C) 2003 Apple Computer, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef kjs_events_h +#define kjs_events_h + +#include "EventListener.h" +#include "PlatformString.h" +#include "kjs_dom.h" +#include "kjs_html.h" +#include <kjs/protect.h> + +namespace KJS { + class Window; +} + +namespace WebCore { + + class Clipboard; + class Event; + + class JSAbstractEventListener : public EventListener { + public: + JSAbstractEventListener(bool html = false); + + virtual void handleEvent(Event*, bool isWindowEvent); + virtual bool isHTMLEventListener() const; + virtual KJS::JSObject* listenerObj() const = 0; + virtual KJS::Window* windowObj() const = 0; + + private: + bool m_html; + }; + + class JSUnprotectedEventListener : public JSAbstractEventListener { + public: + JSUnprotectedEventListener(KJS::JSObject* listener, KJS::Window*, bool html = false); + virtual ~JSUnprotectedEventListener(); + + virtual KJS::JSObject* listenerObj() const; + virtual KJS::Window* windowObj() const; + void clearWindowObj(); + void mark(); + private: + KJS::JSObject* m_listener; + KJS::Window* m_win; + }; + + class JSEventListener : public JSAbstractEventListener { + public: + JSEventListener(KJS::JSObject* listener, KJS::Window*, bool html = false); + virtual ~JSEventListener(); + + virtual KJS::JSObject* listenerObj() const; + virtual KJS::Window* windowObj() const; + void clearWindowObj(); + + protected: + mutable KJS::ProtectedPtr<KJS::JSObject> m_listener; + + private: + KJS::ProtectedPtr<KJS::Window> m_win; + }; + + class JSLazyEventListener : public JSEventListener { + public: + JSLazyEventListener(const String& functionName, const String& code, KJS::Window*, Node*, int lineNumber = 0); + virtual KJS::JSObject* listenerObj() const; + + private: + virtual KJS::JSValue* eventParameterName() const; + void parseCode() const; + + mutable String m_functionName; + mutable String m_code; + mutable bool m_parsed; + int m_lineNumber; + Node* m_originalNode; + }; + + KJS::JSValue* getNodeEventListener(Node*, const AtomicString& eventType); + + class JSClipboard : public DOMObject { + public: + JSClipboard(KJS::JSObject* prototype, Clipboard*); + virtual ~JSClipboard(); + + virtual bool getOwnPropertySlot(KJS::ExecState*, const KJS::Identifier&, KJS::PropertySlot&); + KJS::JSValue* getValueProperty(KJS::ExecState*, int token) const; + virtual void put(KJS::ExecState*, const KJS::Identifier&, KJS::JSValue*); + void putValueProperty(KJS::ExecState*, int token, KJS::JSValue*); + + virtual const KJS::ClassInfo* classInfo() const { return &info; } + static const KJS::ClassInfo info; + + enum { ClearData, GetData, SetData, Types, SetDragImage, DropEffect, EffectAllowed }; + + Clipboard* impl() const { return m_impl.get(); } + + private: + RefPtr<Clipboard> m_impl; + }; + + KJS::JSValue* toJS(KJS::ExecState*, Clipboard*); + Clipboard* toClipboard(KJS::JSValue*); + + // Functions + KJS::JSValue* jsClipboardPrototypeFunctionClearData(KJS::ExecState*, KJS::JSObject*, const KJS::List&); + KJS::JSValue* jsClipboardPrototypeFunctionGetData(KJS::ExecState*, KJS::JSObject*, const KJS::List&); + KJS::JSValue* jsClipboardPrototypeFunctionSetData(KJS::ExecState*, KJS::JSObject*, const KJS::List&); + KJS::JSValue* jsClipboardPrototypeFunctionSetDragImage(KJS::ExecState*, KJS::JSObject*, const KJS::List&); + +} // namespace WebCore + +#endif // kjs_events_h diff --git a/WebCore/bindings/js/kjs_html.cpp b/WebCore/bindings/js/kjs_html.cpp new file mode 100644 index 0000000..8f2c7c4 --- /dev/null +++ b/WebCore/bindings/js/kjs_html.cpp @@ -0,0 +1,142 @@ +// -*- c-basic-offset: 4 -*- +/* + * This file is part of the KDE libraries + * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) + * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "kjs_html.h" + +#include "Frame.h" +#include "FrameLoader.h" +#include "JSHTMLElement.h" +#include "HTMLDocument.h" +#include "HTMLImageElement.h" +#include "kjs_proxy.h" + +namespace WebCore { + +using namespace KJS; + +ImageConstructorImp::ImageConstructorImp(ExecState* exec, Document* doc) + : DOMObject(exec->lexicalGlobalObject()->objectPrototype()) + , m_doc(doc) +{ +} + +JSObject* ImageConstructorImp::construct(ExecState* exec, const List& list) +{ + bool widthSet = false; + bool heightSet = false; + int width = 0; + int height = 0; + + if (list.size() > 0) { + widthSet = true; + JSValue* w = list.at(0); + width = w->toInt32(exec); + } + + if (list.size() > 1) { + heightSet = true; + JSValue* h = list.at(1); + height = h->toInt32(exec); + } + + // Calling toJS on the document causes the JS document wrapper to be + // added to the window object. This is done to ensure that JSDocument::mark + // will be called (which will cause the image element to be marked if necessary). + // This is only a problem for elements created using the Image constructor since all + // other elements are created through the document, using document.createElement for example. + toJS(exec, m_doc.get()); + + HTMLImageElement* image = new HTMLImageElement(m_doc.get()); + JSObject* result = static_cast<JSObject*>(toJS(exec, image)); + + if (widthSet) + image->setWidth(width); + if (heightSet) + image->setHeight(height); + + return result; +} + +// ------------------------------------------------------------------------- + +// Runtime object support code for JSHTMLAppletElement, JSHTMLEmbedElement and JSHTMLObjectElement. + +JSValue* runtimeObjectGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot) +{ + JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(slot.slotBase()); + HTMLElement* element = static_cast<HTMLElement*>(thisObj->impl()); + return getRuntimeObject(exec, element); +} + +JSValue* runtimeObjectPropertyGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot) +{ + JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(slot.slotBase()); + HTMLElement* element = static_cast<HTMLElement*>(thisObj->impl()); + JSObject* runtimeObject = getRuntimeObject(exec, element); + if (!runtimeObject) + return jsUndefined(); + return runtimeObject->get(exec, propertyName); +} + +bool runtimeObjectCustomGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot, JSHTMLElement* originalObj, HTMLElement* thisImp) +{ + JSObject* runtimeObject = getRuntimeObject(exec, thisImp); + if (!runtimeObject) + return false; + if (!runtimeObject->hasProperty(exec, propertyName)) + return false; + slot.setCustom(originalObj, runtimeObjectPropertyGetter); + return true; +} + +bool runtimeObjectCustomPut(ExecState* exec, const Identifier& propertyName, JSValue* value, HTMLElement* thisImp) +{ + JSObject* runtimeObject = getRuntimeObject(exec, thisImp); + if (!runtimeObject) + return 0; + if (!runtimeObject->hasProperty(exec, propertyName)) + return false; + runtimeObject->put(exec, propertyName, value); + return true; +} + +bool runtimeObjectImplementsCall(HTMLElement* thisImp) +{ + Frame* frame = thisImp->document()->frame(); + if (!frame) + return false; + ExecState* exec = frame->scriptProxy()->globalObject()->globalExec(); + JSObject* runtimeObject = getRuntimeObject(exec, thisImp); + if (!runtimeObject) + return false; + return runtimeObject->implementsCall(); +} + +JSValue* runtimeObjectCallAsFunction(ExecState* exec, JSObject* thisObj, const List& args, HTMLElement* thisImp) +{ + JSObject* runtimeObject = getRuntimeObject(exec, thisImp); + if (!runtimeObject) + return jsUndefined(); + return runtimeObject->call(exec, thisObj, args); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/kjs_html.h b/WebCore/bindings/js/kjs_html.h new file mode 100644 index 0000000..4b519d2 --- /dev/null +++ b/WebCore/bindings/js/kjs_html.h @@ -0,0 +1,57 @@ +// -*- c-basic-offset: 2 -*- +/* + * Copyright (C) 1999 Harri Porten (porten@kde.org) + * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef kjs_html_h +#define kjs_html_h + +#include "kjs_dom.h" + +namespace WebCore { + + class Document; + class HTMLCollection; + class HTMLElement; + class JSHTMLElement; + + class ImageConstructorImp : public DOMObject { + public: + ImageConstructorImp(KJS::ExecState*, Document*); + + virtual bool implementsConstruct() const { return true; } + virtual KJS::JSObject* construct(KJS::ExecState*, const KJS::List&); + + private: + RefPtr<Document> m_doc; + }; + + + // Runtime object support code for JSHTMLAppletElement, JSHTMLEmbedElement and JSHTMLObjectElement. + // FIXME: Move these to a more appropriate place. + + KJS::JSValue* runtimeObjectGetter(KJS::ExecState*, KJS::JSObject*, const KJS::Identifier&, const KJS::PropertySlot&); + KJS::JSValue* runtimeObjectPropertyGetter(KJS::ExecState*, KJS::JSObject*, const KJS::Identifier&, const KJS::PropertySlot&); + bool runtimeObjectCustomGetOwnPropertySlot(KJS::ExecState*, const KJS::Identifier&, KJS::PropertySlot&, JSHTMLElement*, HTMLElement*); + bool runtimeObjectCustomPut(KJS::ExecState*, const KJS::Identifier&, KJS::JSValue*, HTMLElement*); + bool runtimeObjectImplementsCall(HTMLElement*); + KJS::JSValue* runtimeObjectCallAsFunction(KJS::ExecState*, KJS::JSObject*, const KJS::List&, HTMLElement*); + +} // namespace WebCore + +#endif // kjs_html_h diff --git a/WebCore/bindings/js/kjs_navigator.cpp b/WebCore/bindings/js/kjs_navigator.cpp new file mode 100644 index 0000000..6e9fbbd --- /dev/null +++ b/WebCore/bindings/js/kjs_navigator.cpp @@ -0,0 +1,620 @@ +/* + * Copyright (C) 2000 Harri Porten (porten@kde.org) + * Copyright (c) 2000 Daniel Molkentin (molkentin@kde.org) + * Copyright (c) 2000 Stefan Schimanski (schimmi@kde.org) + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "kjs_navigator.h" + +#include "AtomicString.h" +#include "CookieJar.h" +#include "DOMWindow.h" +#include "Document.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "Language.h" +#include "Page.h" +#include "PluginInfoStore.h" +#include "Settings.h" +#include "kjs_window.h" +#include <kjs/object_object.h> + +#ifndef WEBCORE_NAVIGATOR_PLATFORM +#if PLATFORM(MAC) && PLATFORM(PPC) +#define WEBCORE_NAVIGATOR_PLATFORM "MacPPC" +#elif PLATFORM(MAC) && PLATFORM(X86) +#define WEBCORE_NAVIGATOR_PLATFORM "MacIntel" +#elif PLATFORM(WIN_OS) +#define WEBCORE_NAVIGATOR_PLATFORM "Win32" +#else +#define WEBCORE_NAVIGATOR_PLATFORM "" +#endif +#endif // ifndef WEBCORE_NAVIGATOR_PLATFORM + +#ifndef WEBCORE_NAVIGATOR_PRODUCT +#define WEBCORE_NAVIGATOR_PRODUCT "Gecko" +#endif // ifndef WEBCORE_NAVIGATOR_PRODUCT + +#ifndef WEBCORE_NAVIGATOR_PRODUCT_SUB +#define WEBCORE_NAVIGATOR_PRODUCT_SUB "20030107" +#endif // ifndef WEBCORE_NAVIGATOR_PRODUCT_SUB + +#ifndef WEBCORE_NAVIGATOR_VENDOR +#define WEBCORE_NAVIGATOR_VENDOR "Apple Computer, Inc." +#endif // ifndef WEBCORE_NAVIGATOR_VENDOR + +#ifndef WEBCORE_NAVIGATOR_VENDOR_SUB +#define WEBCORE_NAVIGATOR_VENDOR_SUB "" +#endif // ifndef WEBCORE_NAVIGATOR_VENDOR_SUB + +using namespace KJS; +using namespace WebCore; + +namespace WebCore { + + class PluginBase : public DOMObject { + public: + PluginBase(ExecState*); + virtual ~PluginBase(); + + static void refresh(bool reload); + + protected: + static void cachePluginDataIfNecessary(); + static Vector<PluginInfo*>* plugins; + static Vector<MimeClassInfo*>* mimes; + + private: + static int m_plugInCacheRefCount; + }; + + + class Plugins : public PluginBase { + public: + Plugins(ExecState* exec) : PluginBase(exec) { } + virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); + JSValue* getValueProperty(ExecState*, int token) const; + virtual const ClassInfo* classInfo() const { return &info; } + static const ClassInfo info; + enum { Length }; + private: + static JSValue* indexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&); + static JSValue* nameGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&); + }; + + JSValue* pluginsFunctionRefresh(ExecState*, JSObject*, const List&); + + class MimeTypes : public PluginBase { + public: + MimeTypes(ExecState* exec) : PluginBase(exec) { }; + virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); + JSValue* getValueProperty(ExecState*, int token) const; + virtual const ClassInfo* classInfo() const { return &info; } + static const ClassInfo info; + enum { Length }; + private: + static JSValue* indexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&); + static JSValue* nameGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&); + }; + + class Plugin : public PluginBase { + public: + Plugin(ExecState* exec, PluginInfo* info) : PluginBase(exec), m_info(info) { } + virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); + JSValue* getValueProperty(ExecState*, int token) const; + virtual const ClassInfo* classInfo() const { return &info; } + static const ClassInfo info; + enum { Name, Filename, Description, Length }; + private: + static JSValue* indexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&); + static JSValue* nameGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&); + + PluginInfo* m_info; + }; + + class MimeType : public PluginBase { + public: + MimeType(ExecState* exec, MimeClassInfo* info) : PluginBase(exec), m_info(info) { } + virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); + JSValue* getValueProperty(ExecState*, int token) const; + virtual const ClassInfo* classInfo() const { return &info; } + static const ClassInfo info; + enum { Type, Suffixes, Description, EnabledPlugin }; + private: + MimeClassInfo* m_info; + }; + +} + +#include "kjs_navigator.lut.h" + +namespace WebCore { + +const ClassInfo Plugins::info = { "PluginArray", 0, &PluginsTable }; +const ClassInfo MimeTypes::info = { "MimeTypeArray", 0, &MimeTypesTable }; +const ClassInfo Plugin::info = { "Plugin", 0, &PluginTable }; +const ClassInfo MimeType::info = { "MimeType", 0, &MimeTypeTable }; + +Vector<PluginInfo*>* PluginBase::plugins = 0; +Vector<MimeClassInfo*>* PluginBase::mimes = 0; +int PluginBase::m_plugInCacheRefCount = 0; + +const ClassInfo Navigator::info = { "Navigator", 0, &NavigatorTable }; +/* +@begin NavigatorTable 13 + appCodeName Navigator::AppCodeName DontDelete|ReadOnly + appName Navigator::AppName DontDelete|ReadOnly + appVersion Navigator::AppVersion DontDelete|ReadOnly + language Navigator::Language DontDelete|ReadOnly + userAgent Navigator::UserAgent DontDelete|ReadOnly + platform Navigator::Platform DontDelete|ReadOnly + plugins Navigator::_Plugins DontDelete|ReadOnly + mimeTypes Navigator::_MimeTypes DontDelete|ReadOnly + product Navigator::Product DontDelete|ReadOnly + productSub Navigator::ProductSub DontDelete|ReadOnly + vendor Navigator::Vendor DontDelete|ReadOnly + vendorSub Navigator::VendorSub DontDelete|ReadOnly + cookieEnabled Navigator::CookieEnabled DontDelete|ReadOnly + javaEnabled navigatorProtoFuncJavaEnabled DontDelete|Function 0 +@end +*/ + +Navigator::Navigator(JSObject* prototype, Frame* frame) + : DOMObject(prototype) + , m_frame(frame) +{ +} + +bool Navigator::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + return getStaticPropertySlot<Navigator, JSObject>(exec, &NavigatorTable, this, propertyName, slot); +} + +static bool needsYouTubeQuirk(ExecState*, Frame*); + +#if !PLATFORM(WIN) + +static inline bool needsYouTubeQuirk(ExecState*, Frame*) +{ + return false; +} + +#else + +static bool needsYouTubeQuirk(ExecState* exec, Frame* frame) +{ + // This quirk works around a mistaken check in an ad at youtube.com. + // There's a function called isSafari that returns false if the function + // called isWindows returns true; thus the site malfunctions with Windows Safari. + + // Do the quirk only if the function's name is "isWindows". + FunctionImp* function = exec->function(); + if (!function) + return false; + static const Identifier& isWindowsFunctionName = *new Identifier("isWindows"); + if (function->functionName() != isWindowsFunctionName) + return false; + + // Do the quirk only if the function is called by an "isSafari" function. + // However, that function is not itself named -- it is stored in the isSafari + // property, though, so that's how we recognize it. + ExecState* callingExec = exec->callingExecState(); + if (!callingExec) + return false; + FunctionImp* callingFunction = callingExec->function(); + if (!callingFunction) + return false; + JSObject* thisObject = callingExec->thisValue(); + if (!thisObject) + return false; + static const Identifier& isSafariFunctionName = *new Identifier("isSafari"); + JSValue* isSafariFunction = thisObject->getDirect(isSafariFunctionName); + if (isSafariFunction != callingFunction) + return false; + + Document* document = frame->document(); + // FIXME: The document is never null, so we should remove this check along with the + // other similar ones in this file when we are absolutely sure it's safe. + if (!document) + return false; + + // Do the quirk only on the front page of the global version of YouTube. + const KURL& url = document->url(); + if (url.host() != "youtube.com" && url.host() != "www.youtube.com") + return false; + if (url.path() != "/") + return false; + + // As with other site-specific quirks, allow website developers to turn this off. + // In theory, this allows website developers to check if their fixes are effective. + Settings* settings = frame->settings(); + if (!settings) + return false; + if (!settings->needsSiteSpecificQuirks()) + return false; + + return true; +} + +#endif + +JSValue* Navigator::getValueProperty(ExecState* exec, int token) const +{ + switch (token) { + case AppCodeName: + return jsString("Mozilla"); + case AppName: + return jsString("Netscape"); + case AppVersion: { + if (needsYouTubeQuirk(exec, m_frame)) + return jsString(""); + // Version is everything in the user agent string past the "Mozilla/" prefix. + const String userAgent = m_frame->loader()->userAgent(m_frame->document() ? m_frame->document()->url() : KURL()); + return jsString(userAgent.substring(userAgent.find('/') + 1)); + } + case Product: + return jsString(WEBCORE_NAVIGATOR_PRODUCT); + case ProductSub: + return jsString(WEBCORE_NAVIGATOR_PRODUCT_SUB); + case Vendor: + return jsString(WEBCORE_NAVIGATOR_VENDOR); + case VendorSub: + return jsString(WEBCORE_NAVIGATOR_VENDOR_SUB); + case Language: + return jsString(defaultLanguage()); + case UserAgent: + return jsString(m_frame->loader()->userAgent(m_frame->document() ? m_frame->document()->url() : KURL())); + case Platform: + return jsString(WEBCORE_NAVIGATOR_PLATFORM); + case _Plugins: + return new Plugins(exec); + case _MimeTypes: + return new MimeTypes(exec); + case CookieEnabled: + return jsBoolean(cookiesEnabled(m_frame->document())); + } + return 0; +} + +/*******************************************************************/ + +void PluginBase::cachePluginDataIfNecessary() +{ + if (!plugins) { + plugins = new Vector<PluginInfo*>; + mimes = new Vector<MimeClassInfo*>; + + // read configuration + PluginInfoStore c; + unsigned pluginCount = c.pluginCount(); + for (unsigned n = 0; n < pluginCount; n++) { + PluginInfo* plugin = c.createPluginInfoForPluginAtIndex(n); + if (!plugin) + continue; + + plugins->append(plugin); + if (plugin->mimes.isEmpty()) + continue; + + Vector<MimeClassInfo*>::iterator end = plugin->mimes.end(); + for (Vector<MimeClassInfo*>::iterator itr = plugin->mimes.begin(); itr != end; itr++) + mimes->append(*itr); + } + } +} + +PluginBase::PluginBase(ExecState* exec) + : DOMObject(exec->lexicalGlobalObject()->objectPrototype()) +{ + cachePluginDataIfNecessary(); + m_plugInCacheRefCount++; +} + +PluginBase::~PluginBase() +{ + m_plugInCacheRefCount--; + if (!m_plugInCacheRefCount) { + if (plugins) { + deleteAllValues(*plugins); + delete plugins; + plugins = 0; + } + if (mimes) { + deleteAllValues(*mimes); + delete mimes; + mimes = 0; + } + } +} + +void PluginBase::refresh(bool reload) +{ + if (plugins) { + deleteAllValues(*plugins); + delete plugins; + plugins = 0; + } + if (mimes) { + deleteAllValues(*mimes); + delete mimes; + mimes = 0; + } + + refreshPlugins(reload); + cachePluginDataIfNecessary(); +} + + +/*******************************************************************/ + +/* +@begin PluginsTable 2 + length Plugins::Length DontDelete|ReadOnly + refresh pluginsFunctionRefresh DontDelete|Function 0 +@end +*/ + +JSValue* Plugins::getValueProperty(ExecState* exec, int token) const +{ + ASSERT(token == Length); + return jsNumber(plugins->size()); +} + +JSValue* Plugins::indexGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot) +{ + return new Plugin(exec, plugins->at(slot.index())); +} + +JSValue* Plugins::nameGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot) +{ + AtomicString atomicPropertyName = propertyName; + Vector<PluginInfo*>::iterator end = plugins->end(); + for (Vector<PluginInfo*>::iterator itr = plugins->begin(); itr != end; itr++) { + PluginInfo* pl = *itr; + if (pl->name == atomicPropertyName) + return new Plugin(exec, pl); + } + return jsUndefined(); +} + +bool Plugins::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + const HashEntry* entry = Lookup::findEntry(&PluginsTable, propertyName); + if (entry) { + if (entry->attr & Function) + slot.setStaticEntry(this, entry, staticFunctionGetter); + else + slot.setStaticEntry(this, entry, staticValueGetter<Plugins>); + return true; + } else { + // plugins[#] + bool ok; + unsigned int i = propertyName.toUInt32(&ok); + if (ok && i < plugins->size()) { + slot.setCustomIndex(this, i, indexGetter); + return true; + } + + // plugin[name] + AtomicString atomicPropertyName = propertyName; + Vector<PluginInfo*>::iterator end = plugins->end(); + for (Vector<PluginInfo*>::iterator itr = plugins->begin(); itr != end; itr++) { + if ((*itr)->name == atomicPropertyName) { + slot.setCustom(this, nameGetter); + return true; + } + } + } + + return PluginBase::getOwnPropertySlot(exec, propertyName, slot); +} + +/*******************************************************************/ + +/* +@begin MimeTypesTable 1 + length MimeTypes::Length DontDelete|ReadOnly +@end +*/ + +JSValue* MimeTypes::getValueProperty(ExecState* exec, int token) const +{ + ASSERT(token == Length); + return jsNumber(mimes->size()); +} + +JSValue* MimeTypes::indexGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot) +{ + return new MimeType(exec, mimes->at(slot.index())); +} + +JSValue* MimeTypes::nameGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot) +{ + AtomicString atomicPropertyName = propertyName; + Vector<MimeClassInfo*>::iterator end = mimes->end(); + for (Vector<MimeClassInfo*>::iterator itr = mimes->begin(); itr != end; itr++) { + MimeClassInfo* m = (*itr); + if (m->type == atomicPropertyName) + return new MimeType(exec, m); + } + return jsUndefined(); +} + +bool MimeTypes::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + const HashEntry* entry = Lookup::findEntry(&MimeTypesTable, propertyName); + if (entry) { + slot.setStaticEntry(this, entry, staticValueGetter<MimeTypes>); + return true; + } else { + // mimeTypes[#] + bool ok; + unsigned int i = propertyName.toUInt32(&ok); + if (ok && i < mimes->size()) { + slot.setCustomIndex(this, i, indexGetter); + return true; + } + + // mimeTypes[name] + AtomicString atomicPropertyName = propertyName; + Vector<MimeClassInfo*>::iterator end = mimes->end(); + for (Vector<MimeClassInfo*>::iterator itr = mimes->begin(); itr != end; itr++) { + if ((*itr)->type == atomicPropertyName) { + slot.setCustom(this, nameGetter); + return true; + } + } + } + + return PluginBase::getOwnPropertySlot(exec, propertyName, slot); +} + + +/************************************************************************/ + +/* +@begin PluginTable 4 + name Plugin::Name DontDelete|ReadOnly + filename Plugin::Filename DontDelete|ReadOnly + description Plugin::Description DontDelete|ReadOnly + length Plugin::Length DontDelete|ReadOnly +@end +*/ + +JSValue* Plugin::getValueProperty(ExecState* exec, int token) const +{ + switch (token) { + case Name: + return jsString(m_info->name); + case Filename: + return jsString(m_info->file); + case Description: + return jsString(m_info->desc); + case Length: + return jsNumber(m_info->mimes.size()); + default: + ASSERT(0); + return jsUndefined(); + } +} + +JSValue* Plugin::indexGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot) +{ + Plugin* thisObj = static_cast<Plugin*>(slot.slotBase()); + return new MimeType(exec, thisObj->m_info->mimes.at(slot.index())); +} + +JSValue* Plugin::nameGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot) +{ + Plugin* thisObj = static_cast<Plugin*>(slot.slotBase()); + AtomicString atomicPropertyName = propertyName; + Vector<MimeClassInfo*>::iterator end = thisObj->m_info->mimes.end(); + for (Vector<MimeClassInfo*>::iterator itr = thisObj->m_info->mimes.begin(); itr != end; itr++) { + MimeClassInfo* m = (*itr); + if (m->type == atomicPropertyName) + return new MimeType(exec, m); + } + return jsUndefined(); +} + + +bool Plugin::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + const HashEntry* entry = Lookup::findEntry(&PluginTable, propertyName); + if (entry) { + slot.setStaticEntry(this, entry, staticValueGetter<Plugin>); + return true; + } else { + // plugin[#] + bool ok; + unsigned int i = propertyName.toUInt32(&ok); + if (ok && i < m_info->mimes.size()) { + slot.setCustomIndex(this, i, indexGetter); + return true; + } + + // plugin["name"] + AtomicString atomicPropertyName = propertyName; + Vector<MimeClassInfo*>::iterator end = m_info->mimes.end(); + for (Vector<MimeClassInfo*>::iterator itr = m_info->mimes.begin(); itr != end; itr++) { + if ((*itr)->type == atomicPropertyName) { + slot.setCustom(this, nameGetter); + return true; + } + } + } + + return PluginBase::getOwnPropertySlot(exec, propertyName, slot); +} + +/*****************************************************************************/ + +/* +@begin MimeTypeTable 4 + type MimeType::Type DontDelete|ReadOnly + suffixes MimeType::Suffixes DontDelete|ReadOnly + description MimeType::Description DontDelete|ReadOnly + enabledPlugin MimeType::EnabledPlugin DontDelete|ReadOnly +@end +*/ + +JSValue* MimeType::getValueProperty(ExecState* exec, int token) const +{ + switch (token) { + case Type: + return jsString(m_info->type); + case Suffixes: + return jsString(m_info->suffixes); + case Description: + return jsString(m_info->desc); + case EnabledPlugin: { + Frame* frame = Window::retrieveActive(exec)->impl()->frame(); + ASSERT(frame); + Settings* settings = frame->settings(); + if (settings && settings->arePluginsEnabled()) + return new Plugin(exec, m_info->plugin); + else + return jsUndefined(); + } + default: + return jsUndefined(); + } +} + +bool MimeType::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + return getStaticValueSlot<MimeType, PluginBase>(exec, &MimeTypeTable, this, propertyName, slot); +} + +JSValue* pluginsFunctionRefresh(ExecState* exec, JSObject*, const List& args) +{ + PluginBase::refresh(args[0]->toBoolean(exec)); + return jsUndefined(); +} + +JSValue* navigatorProtoFuncJavaEnabled(ExecState* exec, JSObject* thisObj, const List&) +{ + if (!thisObj->inherits(&Navigator::info)) + return throwError(exec, TypeError); + Navigator* nav = static_cast<Navigator*>(thisObj); + Settings* settings = nav->frame() ? nav->frame()->settings() : 0; + return jsBoolean(settings && settings->isJavaEnabled()); +} + +} // namespace diff --git a/WebCore/bindings/js/kjs_navigator.h b/WebCore/bindings/js/kjs_navigator.h new file mode 100644 index 0000000..e16f7ea --- /dev/null +++ b/WebCore/bindings/js/kjs_navigator.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2000 Harri Porten (porten@kde.org) + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef kjs_navigator_h +#define kjs_navigator_h + +#include "kjs_binding.h" + +namespace WebCore { + + class Frame; + + class Navigator : public DOMObject { + public: + Navigator(KJS::JSObject* prototype, Frame*); + + virtual bool getOwnPropertySlot(KJS::ExecState*, const KJS::Identifier&, KJS::PropertySlot&); + KJS::JSValue* getValueProperty(KJS::ExecState*, int token) const; + virtual const KJS::ClassInfo* classInfo() const { return &info; } + static const KJS::ClassInfo info; + + enum { AppCodeName, AppName, AppVersion, Language, UserAgent, Platform, + _Plugins, _MimeTypes, Product, ProductSub, Vendor, VendorSub, CookieEnabled }; + + Frame* frame() const { return m_frame; } + + private: + Frame* m_frame; + }; + + KJS::JSValue* navigatorProtoFuncJavaEnabled(KJS::ExecState*, KJS::JSObject*, const KJS::List&); + +} // namespace + +#endif diff --git a/WebCore/bindings/js/kjs_proxy.cpp b/WebCore/bindings/js/kjs_proxy.cpp new file mode 100644 index 0000000..7b29b4b --- /dev/null +++ b/WebCore/bindings/js/kjs_proxy.cpp @@ -0,0 +1,196 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "kjs_proxy.h" + +#include "Chrome.h" +#include "Document.h" +#include "Event.h" +#include "EventNames.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "GCController.h" +#include "JSDocument.h" +#include "JSDOMWindow.h" +#include "Page.h" +#include "Settings.h" +#include "kjs_events.h" +#include "kjs_window.h" + +#if ENABLE(SVG) +#include "JSSVGLazyEventListener.h" +#endif + +using namespace KJS; +using namespace WebCore::EventNames; + +namespace WebCore { + +KJSProxy::KJSProxy(Frame* frame) + : m_frame(frame) + , m_handlerLineno(0) + , m_processingTimerCallback(0) + , m_processingInlineCode(0) +{ +} + +KJSProxy::~KJSProxy() +{ + if (m_globalObject) { + m_globalObject = 0; + + // It's likely that releasing the global object has created a lot of garbage. + gcController().garbageCollectSoon(); + } +} + +JSValue* KJSProxy::evaluate(const String& filename, int baseLine, const String& str) +{ + // evaluate code. Returns the JS return value or 0 + // if there was none, an error occured or the type couldn't be converted. + + initScriptIfNeeded(); + // inlineCode is true for <a href="javascript:doSomething()"> + // and false for <script>doSomething()</script>. Check if it has the + // expected value in all cases. + // See smart window.open policy for where this is used. + ExecState* exec = m_globalObject->globalExec(); + m_processingInlineCode = filename.isNull(); + + JSLock lock; + + // Evaluating the JavaScript could cause the frame to be deallocated + // so we start the keep alive timer here. + m_frame->keepAlive(); + + JSValue* thisNode = Window::retrieve(m_frame); + + m_globalObject->startTimeoutCheck(); + Completion comp = Interpreter::evaluate(exec, filename, baseLine, reinterpret_cast<const KJS::UChar*>(str.characters()), str.length(), thisNode); + m_globalObject->stopTimeoutCheck(); + + if (comp.complType() == Normal || comp.complType() == ReturnValue) { + m_processingInlineCode = false; + return comp.value(); + } + + if (comp.complType() == Throw) { + UString errorMessage = comp.value()->toString(exec); + int lineNumber = comp.value()->toObject(exec)->get(exec, "line")->toInt32(exec); + UString sourceURL = comp.value()->toObject(exec)->get(exec, "sourceURL")->toString(exec); + if (Page* page = m_frame->page()) + page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, errorMessage, lineNumber, sourceURL); + } + + m_processingInlineCode = false; + return 0; +} + +void KJSProxy::clear() +{ + // clear resources allocated by the global object, and make it ready to be used by another page + // We have to keep it, so that the Window object for the frame remains the same. + // (we used to delete and re-create it, previously) + if (m_globalObject) + m_globalObject->clear(); +} + +EventListener* KJSProxy::createHTMLEventHandler(const String& functionName, const String& code, Node* node) +{ + initScriptIfNeeded(); + JSLock lock; + return new JSLazyEventListener(functionName, code, Window::retrieveWindow(m_frame), node, m_handlerLineno); +} + +#if ENABLE(SVG) +EventListener* KJSProxy::createSVGEventHandler(const String& functionName, const String& code, Node* node) +{ + initScriptIfNeeded(); + JSLock lock; + return new JSSVGLazyEventListener(functionName, code, Window::retrieveWindow(m_frame), node, m_handlerLineno); +} +#endif + +void KJSProxy::finishedWithEvent(Event* event) +{ + // This is called when the DOM implementation has finished with a particular event. This + // is the case in sitations where an event has been created just for temporary usage, + // e.g. an image load or mouse move. Once the event has been dispatched, it is forgotten + // by the DOM implementation and so does not need to be cached still by the interpreter + ScriptInterpreter::forgetDOMObject(event); +} + +void KJSProxy::initScript() +{ + if (m_globalObject) + return; + + JSLock lock; + + m_globalObject = new JSDOMWindow(m_frame->domWindow()); + + m_frame->loader()->dispatchWindowObjectAvailable(); +} + +void KJSProxy::clearDocumentWrapper() +{ + if (!m_globalObject) + return; + + JSLock lock; + m_globalObject->removeDirect("document"); +} + +bool KJSProxy::processingUserGesture() const +{ + if (!m_globalObject) + return false; + + if (Event* event = m_globalObject->currentEvent()) { + const AtomicString& type = event->type(); + if ( // mouse events + type == clickEvent || type == mousedownEvent || + type == mouseupEvent || type == dblclickEvent || + // keyboard events + type == keydownEvent || type == keypressEvent || + type == keyupEvent || + // other accepted events + type == selectEvent || type == changeEvent || + type == focusEvent || type == blurEvent || + type == submitEvent) + return true; + } else { // no event + if (m_processingInlineCode && !m_processingTimerCallback) { + // This is the <a href="javascript:window.open('...')> case -> we let it through + return true; + } + // This is the <script>window.open(...)</script> case or a timer callback -> block it + } + return false; +} + +bool KJSProxy::isEnabled() +{ + Settings* settings = m_frame->settings(); + return (settings && settings->isJavaScriptEnabled()); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/kjs_proxy.h b/WebCore/bindings/js/kjs_proxy.h new file mode 100644 index 0000000..c746566 --- /dev/null +++ b/WebCore/bindings/js/kjs_proxy.h @@ -0,0 +1,89 @@ +/* + * This file is part of the KDE libraries + * Copyright (C) 1999 Harri Porten (porten@kde.org) + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef kjs_proxy_h +#define kjs_proxy_h + +#include "JSDOMWindow.h" +#include <kjs/protect.h> +#include <wtf/RefPtr.h> + +namespace KJS { + class JSGlobalObject; + class JSValue; +} + +namespace WebCore { + +class Event; +class EventListener; +class Frame; +class Node; +class String; + +// FIXME: Rename this class to JSController and the Frame function to javaScript(). + +class KJSProxy { +public: + KJSProxy(Frame*); + ~KJSProxy(); + + bool haveGlobalObject() const { return m_globalObject; } + JSDOMWindow* globalObject() + { + initScriptIfNeeded(); + return m_globalObject; + } + + KJS::JSValue* evaluate(const String& filename, int baseLine, const String& code); + void clear(); + EventListener* createHTMLEventHandler(const String& functionName, const String& code, Node*); +#if ENABLE(SVG) + EventListener* createSVGEventHandler(const String& functionName, const String& code, Node*); +#endif + void finishedWithEvent(Event*); + void setEventHandlerLineno(int lineno) { m_handlerLineno = lineno; } + + void clearDocumentWrapper(); + + void setProcessingTimerCallback(bool b) { m_processingTimerCallback = b; } + bool processingUserGesture() const; + + bool isEnabled(); + +private: + void initScriptIfNeeded() + { + if (!m_globalObject) + initScript(); + } + void initScript(); + + KJS::ProtectedPtr<JSDOMWindow> m_globalObject; + Frame* m_frame; + int m_handlerLineno; + + bool m_processingTimerCallback; + bool m_processingInlineCode; +}; + +} + +#endif diff --git a/WebCore/bindings/js/kjs_window.cpp b/WebCore/bindings/js/kjs_window.cpp new file mode 100644 index 0000000..04d65cc --- /dev/null +++ b/WebCore/bindings/js/kjs_window.cpp @@ -0,0 +1,1503 @@ +/* + * Copyright (C) 2000 Harri Porten (porten@kde.org) + * Copyright (C) 2006 Jon Shier (jshier@iastate.edu) + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reseved. + * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#include "config.h" +#include "kjs_window.h" + +#include "Base64.h" +#include "CString.h" +#include "Chrome.h" +#include "DOMWindow.h" +#include "Element.h" +#include "EventListener.h" +#include "EventNames.h" +#include "ExceptionCode.h" +#include "FloatRect.h" +#include "Frame.h" +#include "FrameLoadRequest.h" +#include "FrameLoader.h" +#include "FrameTree.h" +#include "GCController.h" +#include "HTMLDocument.h" +#include "JSDOMWindow.h" +#include "JSEvent.h" +#include "JSAudioConstructor.h" +#include "JSHTMLCollection.h" +#include "JSHTMLOptionElementConstructor.h" +#include "JSXMLHttpRequest.h" +#include "JSLocation.h" +#include "Logging.h" +#include "MediaPlayer.h" +#include "Page.h" +#include "PausedTimeouts.h" +#include "PlatformScreen.h" +#include "PluginInfoStore.h" +#include "RenderView.h" +#include "ScheduledAction.h" +#include "SecurityOrigin.h" +#include "Settings.h" +#include "WindowFeatures.h" +#include "htmlediting.h" +#include "kjs_css.h" +#include "kjs_events.h" +#include "kjs_navigator.h" +#include "kjs_proxy.h" +#include <wtf/AlwaysInline.h> +#include <wtf/MathExtras.h> + +#if ENABLE(XSLT) +#include "JSXSLTProcessor.h" +#endif + +using namespace WebCore; +using namespace EventNames; + +namespace KJS { + +static int lastUsedTimeoutId; + +static int timerNestingLevel = 0; +const int cMaxTimerNestingLevel = 5; +const double cMinimumTimerInterval = 0.010; + +struct WindowPrivate { + WindowPrivate() + : loc(0) + , m_evt(0) + , m_returnValueSlot(0) + { + } + + Window::ListenersMap jsEventListeners; + Window::ListenersMap jsHTMLEventListeners; + Window::UnprotectedListenersMap jsUnprotectedEventListeners; + Window::UnprotectedListenersMap jsUnprotectedHTMLEventListeners; + mutable WebCore::JSLocation* loc; + WebCore::Event* m_evt; + JSValue** m_returnValueSlot; + + typedef HashMap<int, DOMWindowTimer*> TimeoutsMap; + TimeoutsMap m_timeouts; +}; + +class DOMWindowTimer : public TimerBase { +public: + DOMWindowTimer(int timeoutId, int nestingLevel, Window* object, WebCore::ScheduledAction* action) + : m_timeoutId(timeoutId) + , m_nestingLevel(nestingLevel) + , m_object(object) + , m_action(action) + { + } + + virtual ~DOMWindowTimer() + { + JSLock lock; + delete m_action; + } + + int timeoutId() const { return m_timeoutId; } + + int nestingLevel() const { return m_nestingLevel; } + void setNestingLevel(int n) { m_nestingLevel = n; } + + WebCore::ScheduledAction* action() const { return m_action; } + WebCore::ScheduledAction* takeAction() { WebCore::ScheduledAction* a = m_action; m_action = 0; return a; } + +private: + virtual void fired(); + + int m_timeoutId; + int m_nestingLevel; + Window* m_object; + WebCore::ScheduledAction* m_action; +}; + +} // namespace KJS + +#include "kjs_window.lut.h" + +namespace KJS { + +////////////////////// Window Object //////////////////////// + +const ClassInfo Window::info = { "Window", 0, &WindowTable }; + +/* +@begin WindowTable 118 +# Warning, when adding a function to this object you need to add a case in Window::get +# -- Functions -- + atob windowProtoFuncAToB DontDelete|Function 1 + btoa windowProtoFuncBToA DontDelete|Function 1 + open windowProtoFuncOpen DontDelete|Function 3 + setTimeout windowProtoFuncSetTimeout DontDelete|Function 2 + clearTimeout windowProtoFuncClearTimeout DontDelete|Function 1 + setInterval windowProtoFuncSetInterval DontDelete|Function 2 + clearInterval windowProtoFuncClearTimeout DontDelete|Function 1 + addEventListener windowProtoFuncAddEventListener DontDelete|Function 3 + removeEventListener windowProtoFuncRemoveEventListener DontDelete|Function 3 + showModalDialog windowProtoFuncShowModalDialog DontDelete|Function 1 +# Not implemented + captureEvents windowProtoFuncNotImplemented DontDelete|Function 0 + releaseEvents windowProtoFuncNotImplemented DontDelete|Function 0 + +# -- Attributes -- + crypto Window::Crypto DontDelete|ReadOnly + event Window::Event_ DontDelete + location Window::Location_ DontDelete + navigator Window::Navigator_ DontDelete + clientInformation Window::ClientInformation DontDelete +# -- Event Listeners -- + onabort Window::Onabort DontDelete + onblur Window::Onblur DontDelete + onchange Window::Onchange DontDelete + onclick Window::Onclick DontDelete + ondblclick Window::Ondblclick DontDelete + onerror Window::Onerror DontDelete + onfocus Window::Onfocus DontDelete + onkeydown Window::Onkeydown DontDelete + onkeypress Window::Onkeypress DontDelete + onkeyup Window::Onkeyup DontDelete + onload Window::Onload DontDelete + onmousedown Window::Onmousedown DontDelete + onmousemove Window::Onmousemove DontDelete + onmouseout Window::Onmouseout DontDelete + onmouseover Window::Onmouseover DontDelete + onmouseup Window::Onmouseup DontDelete + onmousewheel Window::OnWindowMouseWheel DontDelete + onreset Window::Onreset DontDelete + onresize Window::Onresize DontDelete + onscroll Window::Onscroll DontDelete + onsearch Window::Onsearch DontDelete + onselect Window::Onselect DontDelete + onsubmit Window::Onsubmit DontDelete + onunload Window::Onunload DontDelete + onbeforeunload Window::Onbeforeunload DontDelete +# -- Constructors -- + Audio Window::Audio DontDelete + Image Window::Image DontDelete + Option Window::Option DontDelete + XMLHttpRequest Window::XMLHttpRequest DontDelete + XSLTProcessor Window::XSLTProcessor_ DontDelete +@end +*/ + +Window::Window(JSObject* prototype, DOMWindow* window) + : JSGlobalObject(prototype) + , m_impl(window) + , d(new WindowPrivate) +{ + // Window destruction is not thread-safe because of + // the non-thread-safe WebCore structures it references. + Collector::collectOnMainThreadOnly(this); + + // Time in milliseconds before the script timeout handler kicks in. + setTimeoutTime(10000); +} + +Window::~Window() +{ + clearAllTimeouts(); + + // Clear any backpointers to the window + + ListenersMap::iterator i2 = d->jsEventListeners.begin(); + ListenersMap::iterator e2 = d->jsEventListeners.end(); + for (; i2 != e2; ++i2) + i2->second->clearWindowObj(); + i2 = d->jsHTMLEventListeners.begin(); + e2 = d->jsHTMLEventListeners.end(); + for (; i2 != e2; ++i2) + i2->second->clearWindowObj(); + + UnprotectedListenersMap::iterator i1 = d->jsUnprotectedEventListeners.begin(); + UnprotectedListenersMap::iterator e1 = d->jsUnprotectedEventListeners.end(); + for (; i1 != e1; ++i1) + i1->second->clearWindowObj(); + i1 = d->jsUnprotectedHTMLEventListeners.begin(); + e1 = d->jsUnprotectedHTMLEventListeners.end(); + for (; i1 != e1; ++i1) + i1->second->clearWindowObj(); +} + +Window* Window::retrieveWindow(Frame* frame) +{ + JSObject* o = retrieve(frame)->getObject(); + + ASSERT(o || !frame->scriptProxy()->isEnabled()); + return static_cast<Window*>(o); +} + +Window* Window::retrieveActive(ExecState* exec) +{ + JSGlobalObject* globalObject = exec->dynamicGlobalObject(); + ASSERT(globalObject); + return static_cast<Window*>(globalObject); +} + +JSValue* Window::retrieve(Frame* frame) +{ + ASSERT(frame); + if (frame->scriptProxy()->isEnabled()) + return frame->scriptProxy()->globalObject(); // the Global object is the "window" + + return jsUndefined(); // This can happen with JS disabled on the domain of that window +} + +WebCore::JSLocation* Window::location() const +{ + if (!d->loc) + d->loc = new JSLocation(0, impl()->frame()); // FIXME: we need to pass a prototype. + return d->loc; +} + +void Window::mark() +{ + Base::mark(); + if (d->loc && !d->loc->marked()) + d->loc->mark(); +} + +static bool allowPopUp(ExecState* exec) +{ + Frame* frame = Window::retrieveActive(exec)->impl()->frame(); + + ASSERT(frame); + if (frame->scriptProxy()->processingUserGesture()) + return true; + Settings* settings = frame->settings(); + return settings && settings->JavaScriptCanOpenWindowsAutomatically(); +} + +static HashMap<String, String> parseModalDialogFeatures(const String& featuresArg) +{ + HashMap<String, String> map; + + Vector<String> features; + featuresArg.split(';', features); + Vector<String>::const_iterator end = features.end(); + for (Vector<String>::const_iterator it = features.begin(); it != end; ++it) { + String s = *it; + int pos = s.find('='); + int colonPos = s.find(':'); + if (pos >= 0 && colonPos >= 0) + continue; // ignore any strings that have both = and : + if (pos < 0) + pos = colonPos; + if (pos < 0) { + // null string for value means key without value + map.set(s.stripWhiteSpace().lower(), String()); + } else { + String key = s.left(pos).stripWhiteSpace().lower(); + String val = s.substring(pos + 1).stripWhiteSpace().lower(); + int spacePos = val.find(' '); + if (spacePos != -1) + val = val.left(spacePos); + map.set(key, val); + } + } + + return map; +} + +static Frame* createWindow(ExecState* exec, Frame* openerFrame, const String& url, + const String& frameName, const WindowFeatures& windowFeatures, JSValue* dialogArgs) +{ + Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame(); + + ResourceRequest request; + if (activeFrame) + request.setHTTPReferrer(activeFrame->loader()->outgoingReferrer()); + FrameLoadRequest frameRequest(request, frameName); + + FrameLoader* loader; + if (activeFrame) + // We need to use the active frame's loader to let FrameLoader know + // which principal is requesting the navigation. Unfortunately, there + // might not be an activeFrame, in which case we resort to using the + // opener's loader. + // + // See http://bugs.webkit.org/show_bug.cgi?id=16522 + loader = activeFrame->loader(); + else + loader = openerFrame->loader(); + + // FIXME: It's much better for client API if a new window starts with a URL, here where we + // know what URL we are going to open. Unfortunately, this code passes the empty string + // for the URL, but there's a reason for that. Before loading we have to set up the opener, + // openedByDOM, and dialogArguments values. Also, to decide whether to use the URL we currently + // do an allowsAccessFrom call using the window we create, which can't be done before creating it. + // We'd have to resolve all those issues to pass the URL instead of "". + + bool created; + Frame* newFrame = loader->createWindow(frameRequest, windowFeatures, created); + if (!newFrame) + return 0; + + newFrame->loader()->setOpener(openerFrame); + newFrame->loader()->setOpenedByDOM(); + + Window* newWindow = Window::retrieveWindow(newFrame); + + if (dialogArgs) + newWindow->putDirect("dialogArguments", dialogArgs); + + if (!protocolIs(url, "javascript") || newWindow->allowsAccessFrom(exec)) { + KURL completedURL = url.isEmpty() ? KURL("") : activeFrame->document()->completeURL(url); + bool userGesture = activeFrame->scriptProxy()->processingUserGesture(); + + if (created) { + newFrame->loader()->changeLocation(completedURL, activeFrame->loader()->outgoingReferrer(), false, userGesture); + if (Document* oldDoc = openerFrame->document()) + newFrame->document()->setBaseURL(oldDoc->baseURL()); + } else if (!url.isEmpty()) + newFrame->loader()->scheduleLocationChange(completedURL.string(), activeFrame->loader()->outgoingReferrer(), false, userGesture); + } + + return newFrame; +} + +static bool canShowModalDialog(const Frame* frame) +{ + if (!frame) + return false; + return frame->page()->chrome()->canRunModal(); +} + +static bool canShowModalDialogNow(const Frame* frame) +{ + if (!frame) + return false; + return frame->page()->chrome()->canRunModalNow(); +} + +static JSValue* showModalDialog(ExecState* exec, Frame* frame, const String& url, JSValue* dialogArgs, const String& featureArgs) +{ + if (!canShowModalDialogNow(frame) || !allowPopUp(exec)) + return jsUndefined(); + + const HashMap<String, String> features = parseModalDialogFeatures(featureArgs); + + const bool trusted = false; + + // The following features from Microsoft's documentation are not implemented: + // - default font settings + // - width, height, left, and top specified in units other than "px" + // - edge (sunken or raised, default is raised) + // - dialogHide: trusted && boolFeature(features, "dialoghide"), makes dialog hide when you print + // - help: boolFeature(features, "help", true), makes help icon appear in dialog (what does it do on Windows?) + // - unadorned: trusted && boolFeature(features, "unadorned"); + + if (!frame) + return jsUndefined(); + + FloatRect screenRect = screenAvailableRect(frame->view()); + + WindowFeatures wargs; + wargs.width = WindowFeatures::floatFeature(features, "dialogwidth", 100, screenRect.width(), 620); // default here came from frame size of dialog in MacIE + wargs.widthSet = true; + wargs.height = WindowFeatures::floatFeature(features, "dialogheight", 100, screenRect.height(), 450); // default here came from frame size of dialog in MacIE + wargs.heightSet = true; + + wargs.x = WindowFeatures::floatFeature(features, "dialogleft", screenRect.x(), screenRect.right() - wargs.width, -1); + wargs.xSet = wargs.x > 0; + wargs.y = WindowFeatures::floatFeature(features, "dialogtop", screenRect.y(), screenRect.bottom() - wargs.height, -1); + wargs.ySet = wargs.y > 0; + + if (WindowFeatures::boolFeature(features, "center", true)) { + if (!wargs.xSet) { + wargs.x = screenRect.x() + (screenRect.width() - wargs.width) / 2; + wargs.xSet = true; + } + if (!wargs.ySet) { + wargs.y = screenRect.y() + (screenRect.height() - wargs.height) / 2; + wargs.ySet = true; + } + } + + wargs.dialog = true; + wargs.resizable = WindowFeatures::boolFeature(features, "resizable"); + wargs.scrollbarsVisible = WindowFeatures::boolFeature(features, "scroll", true); + wargs.statusBarVisible = WindowFeatures::boolFeature(features, "status", !trusted); + wargs.menuBarVisible = false; + wargs.toolBarVisible = false; + wargs.locationBarVisible = false; + wargs.fullscreen = false; + + Frame* dialogFrame = createWindow(exec, frame, url, "", wargs, dialogArgs); + if (!dialogFrame) + return jsUndefined(); + + Window* dialogWindow = Window::retrieveWindow(dialogFrame); + + // Get the return value either just before clearing the dialog window's + // properties (in Window::clear), or when on return from runModal. + JSValue* returnValue = 0; + dialogWindow->setReturnValueSlot(&returnValue); + dialogFrame->page()->chrome()->runModal(); + dialogWindow->setReturnValueSlot(0); + + // If we don't have a return value, get it now. + // Either Window::clear was not called yet, or there was no return value, + // and in that case, there's no harm in trying again (no benefit either). + if (!returnValue) + returnValue = dialogWindow->getDirect("returnValue"); + + return returnValue ? returnValue : jsUndefined(); +} + +JSValue *Window::getValueProperty(ExecState *exec, int token) const +{ + ASSERT(impl()->frame()); + + switch (token) { + case Crypto: + return jsUndefined(); // FIXME: implement this + case Event_: + if (!allowsAccessFrom(exec)) + return jsUndefined(); + if (!d->m_evt) + return jsUndefined(); + return toJS(exec, d->m_evt); + case Location_: + return location(); + case Navigator_: + case ClientInformation: { + if (!allowsAccessFrom(exec)) + return jsUndefined(); + // Store the navigator in the object so we get the same one each time. + Navigator* n = new Navigator(exec->lexicalGlobalObject()->objectPrototype(), impl()->frame()); + // FIXME: this will make the "navigator" object accessible from windows that fail + // the security check the first time, but not subsequent times, seems weird. + const_cast<Window *>(this)->putDirect("navigator", n, DontDelete); + const_cast<Window *>(this)->putDirect("clientInformation", n, DontDelete); + return n; + } + case Image: + if (!allowsAccessFrom(exec)) + return jsUndefined(); + // FIXME: this property (and the few below) probably shouldn't create a new object every + // time + return new ImageConstructorImp(exec, impl()->frame()->document()); + case Option: + if (!allowsAccessFrom(exec)) + return jsUndefined(); + return new JSHTMLOptionElementConstructor(exec, impl()->frame()->document()); + case XMLHttpRequest: + if (!allowsAccessFrom(exec)) + return jsUndefined(); + return new JSXMLHttpRequestConstructorImp(exec, impl()->frame()->document()); + case Audio: +#if ENABLE(VIDEO) + if (!allowsAccessFrom(exec)) + return jsUndefined(); + if (!MediaPlayer::isAvailable()) + return jsUndefined(); + return new JSAudioConstructor(exec, impl()->frame()->document()); +#else + return jsUndefined(); +#endif +#if ENABLE(XSLT) + case XSLTProcessor_: + if (!allowsAccessFrom(exec)) + return jsUndefined(); + return new XSLTProcessorConstructorImp(exec); +#else + case XSLTProcessor_: + return jsUndefined(); +#endif + } + + if (!allowsAccessFrom(exec)) + return jsUndefined(); + + switch (token) { + case Onabort: + return getListener(exec, abortEvent); + case Onblur: + return getListener(exec, blurEvent); + case Onchange: + return getListener(exec, changeEvent); + case Onclick: + return getListener(exec, clickEvent); + case Ondblclick: + return getListener(exec, dblclickEvent); + case Onerror: + return getListener(exec, errorEvent); + case Onfocus: + return getListener(exec, focusEvent); + case Onkeydown: + return getListener(exec, keydownEvent); + case Onkeypress: + return getListener(exec, keypressEvent); + case Onkeyup: + return getListener(exec, keyupEvent); + case Onload: + return getListener(exec, loadEvent); + case Onmousedown: + return getListener(exec, mousedownEvent); + case Onmousemove: + return getListener(exec, mousemoveEvent); + case Onmouseout: + return getListener(exec, mouseoutEvent); + case Onmouseover: + return getListener(exec, mouseoverEvent); + case Onmouseup: + return getListener(exec, mouseupEvent); + case OnWindowMouseWheel: + return getListener(exec, mousewheelEvent); + case Onreset: + return getListener(exec, resetEvent); + case Onresize: + return getListener(exec,resizeEvent); + case Onscroll: + return getListener(exec,scrollEvent); + case Onsearch: + return getListener(exec,searchEvent); + case Onselect: + return getListener(exec,selectEvent); + case Onsubmit: + return getListener(exec,submitEvent); + case Onbeforeunload: + return getListener(exec, beforeunloadEvent); + case Onunload: + return getListener(exec, unloadEvent); + } + ASSERT_NOT_REACHED(); + return jsUndefined(); +} + +JSValue* Window::childFrameGetter(ExecState*, JSObject*, const Identifier& propertyName, const PropertySlot& slot) +{ + return retrieve(static_cast<Window*>(slot.slotBase())->impl()->frame()->tree()->child(AtomicString(propertyName))); +} + +JSValue* Window::indexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot) +{ + return retrieve(static_cast<Window*>(slot.slotBase())->impl()->frame()->tree()->child(slot.index())); +} + +JSValue* Window::namedItemGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot) +{ + Window* thisObj = static_cast<Window*>(slot.slotBase()); + Document* doc = thisObj->impl()->frame()->document(); + ASSERT(thisObj->allowsAccessFrom(exec)); + ASSERT(doc); + ASSERT(doc->isHTMLDocument()); + + RefPtr<WebCore::HTMLCollection> collection = doc->windowNamedItems(propertyName); + if (collection->length() == 1) + return toJS(exec, collection->firstItem()); + return toJS(exec, collection.get()); +} + +bool Window::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + // 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 (impl()->frame()->tree()->child(propertyName)) { + slot.setCustom(this, childFrameGetter); + return true; + } + + const HashEntry* entry = Lookup::findEntry(&WindowTable, propertyName); + if (entry) { + if (entry->attr & Function) { + if (entry->value.functionValue == windowProtoFuncShowModalDialog) { + if (!canShowModalDialog(impl()->frame())) + return false; + } + if (allowsAccessFrom(exec)) + slot.setStaticEntry(this, entry, staticFunctionGetter); + else + slot.setUndefined(this); + } else + slot.setStaticEntry(this, entry, staticValueGetter<Window>); + 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 = prototype(); + if (proto->isObject()) { + if (static_cast<JSObject*>(proto)->getPropertySlot(exec, propertyName, slot)) { + if (!allowsAccessFrom(exec)) + slot.setUndefined(this); + return true; + } + } + + // FIXME: Search the whole frame hierachy somewhere around here. + // We need to test the correct priority order. + + // allow window[1] or parent[1] etc. (#56983) + bool ok; + unsigned i = propertyName.toArrayIndex(&ok); + if (ok && i < impl()->frame()->tree()->childCount()) { + slot.setCustomIndex(this, i, indexGetter); + return true; + } + + if (!allowsAccessFrom(exec)) { + slot.setUndefined(this); + return true; + } + + // Allow shortcuts like 'Image1' instead of document.images.Image1 + Document* doc = impl()->frame()->document(); + if (doc && doc->isHTMLDocument()) { + AtomicString atomicPropertyName = propertyName; + if (static_cast<HTMLDocument*>(doc)->hasNamedItem(atomicPropertyName) || doc->getElementById(atomicPropertyName)) { + slot.setCustom(this, namedItemGetter); + return true; + } + } + + return Base::getOwnPropertySlot(exec, propertyName, slot); +} + +void Window::put(ExecState* exec, const Identifier& propertyName, JSValue* value) +{ + const HashEntry* entry = Lookup::findEntry(&WindowTable, propertyName); + if (entry) { + if (entry->attr & Function) { + if (allowsAccessFrom(exec)) + Base::put(exec, propertyName, value); + return; + } + if (entry->attr & ReadOnly) + return; + + switch (entry->value.intValue) { + case Location_: { + if (Frame* p = Window::retrieveActive(exec)->impl()->frame()) { + // To avoid breaking old widgets, make "var location =" in a top-level frame create + // a property named "location" instead of performing a navigation (<rdar://problem/5688039>). + if (Settings* settings = p->settings()) { + if (settings->usesDashboardBackwardCompatibilityMode() && !p->tree()->parent()) { + if (allowsAccessFrom(exec)) + putDirect(propertyName, value); + return; + } + } + + if (!p->loader()->shouldAllowNavigation(impl()->frame())) + return; + String dstUrl = p->loader()->completeURL(value->toString(exec)).string(); + if (!protocolIs(dstUrl, "javascript") || allowsAccessFrom(exec)) { + bool userGesture = p->scriptProxy()->processingUserGesture(); + // We want a new history item if this JS was called via a user gesture + impl()->frame()->loader()->scheduleLocationChange(dstUrl, p->loader()->outgoingReferrer(), false, userGesture); + } + } + return; + } + case Onabort: + if (allowsAccessFrom(exec)) + setListener(exec, abortEvent,value); + return; + case Onblur: + if (allowsAccessFrom(exec)) + setListener(exec, blurEvent,value); + return; + case Onchange: + if (allowsAccessFrom(exec)) + setListener(exec, changeEvent,value); + return; + case Onclick: + if (allowsAccessFrom(exec)) + setListener(exec,clickEvent,value); + return; + case Ondblclick: + if (allowsAccessFrom(exec)) + setListener(exec, dblclickEvent,value); + return; + case Onerror: + if (allowsAccessFrom(exec)) + setListener(exec, errorEvent, value); + return; + case Onfocus: + if (allowsAccessFrom(exec)) + setListener(exec,focusEvent,value); + return; + case Onkeydown: + if (allowsAccessFrom(exec)) + setListener(exec,keydownEvent,value); + return; + case Onkeypress: + if (allowsAccessFrom(exec)) + setListener(exec,keypressEvent,value); + return; + case Onkeyup: + if (allowsAccessFrom(exec)) + setListener(exec,keyupEvent,value); + return; + case Onload: + if (allowsAccessFrom(exec)) + setListener(exec,loadEvent,value); + return; + case Onmousedown: + if (allowsAccessFrom(exec)) + setListener(exec,mousedownEvent,value); + return; + case Onmousemove: + if (allowsAccessFrom(exec)) + setListener(exec,mousemoveEvent,value); + return; + case Onmouseout: + if (allowsAccessFrom(exec)) + setListener(exec,mouseoutEvent,value); + return; + case Onmouseover: + if (allowsAccessFrom(exec)) + setListener(exec,mouseoverEvent,value); + return; + case Onmouseup: + if (allowsAccessFrom(exec)) + setListener(exec,mouseupEvent,value); + return; + case OnWindowMouseWheel: + if (allowsAccessFrom(exec)) + setListener(exec, mousewheelEvent,value); + return; + case Onreset: + if (allowsAccessFrom(exec)) + setListener(exec,resetEvent,value); + return; + case Onresize: + if (allowsAccessFrom(exec)) + setListener(exec,resizeEvent,value); + return; + case Onscroll: + if (allowsAccessFrom(exec)) + setListener(exec,scrollEvent,value); + return; + case Onsearch: + if (allowsAccessFrom(exec)) + setListener(exec,searchEvent,value); + return; + case Onselect: + if (allowsAccessFrom(exec)) + setListener(exec,selectEvent,value); + return; + case Onsubmit: + if (allowsAccessFrom(exec)) + setListener(exec,submitEvent,value); + return; + case Onbeforeunload: + if (allowsAccessFrom(exec)) + setListener(exec, beforeunloadEvent, value); + return; + case Onunload: + if (allowsAccessFrom(exec)) + setListener(exec, unloadEvent, value); + return; + default: + break; + } + } + if (allowsAccessFrom(exec)) + Base::put(exec, propertyName, value); +} + +bool Window::allowsAccessFrom(const JSGlobalObject* other) const +{ + SecurityOrigin::Reason reason; + if (allowsAccessFromPrivate(other, reason)) + return true; + printErrorMessage(crossDomainAccessErrorMessage(other, reason)); + return false; +} + +bool Window::allowsAccessFrom(ExecState* exec) const +{ + SecurityOrigin::Reason reason; + if (allowsAccessFromPrivate(exec, reason)) + return true; + printErrorMessage(crossDomainAccessErrorMessage(exec->dynamicGlobalObject(), reason)); + return false; +} + +bool Window::allowsAccessFromNoErrorMessage(ExecState* exec) const +{ + SecurityOrigin::Reason reason; + return allowsAccessFromPrivate(exec, reason); +} + +bool Window::allowsAccessFrom(ExecState* exec, String& message) const +{ + SecurityOrigin::Reason reason; + if (allowsAccessFromPrivate(exec, reason)) + return true; + message = crossDomainAccessErrorMessage(exec->dynamicGlobalObject(), reason); + return false; +} + +ALWAYS_INLINE bool Window::allowsAccessFromPrivate(const ExecState* exec, SecurityOrigin::Reason& reason) const +{ + if (allowsAccessFromPrivate(exec->dynamicGlobalObject(), reason)) + return true; + if (reason == SecurityOrigin::DomainSetInDOMMismatch) { + // If the only reason the access failed was a domainSetInDOM bit mismatch, try again against + // lexical global object <rdar://problem/5698200> + if (allowsAccessFromPrivate(exec->lexicalGlobalObject(), reason)) + return true; + } + return false; +} + +ALWAYS_INLINE bool Window::allowsAccessFromPrivate(const JSGlobalObject* other, SecurityOrigin::Reason& reason) const +{ + const Frame* originFrame = static_cast<const Window*>(other)->impl()->frame(); + if (!originFrame) { + reason = SecurityOrigin::GenericMismatch; + return false; + } + + const Frame* targetFrame = impl()->frame(); + + if (originFrame == targetFrame) + return true; + + if (!targetFrame) { + reason = SecurityOrigin::GenericMismatch; + return false; + } + + WebCore::Document* targetDocument = targetFrame->document(); + + // JS may be attempting to access the "window" object, which should be valid, + // even if the document hasn't been constructed yet. If the document doesn't + // exist yet allow JS to access the window object. + if (!targetDocument) + return true; + + WebCore::Document* originDocument = originFrame->document(); + + const SecurityOrigin* originSecurityOrigin = originDocument->securityOrigin(); + const SecurityOrigin* targetSecurityOrigin = targetDocument->securityOrigin(); + + if (originSecurityOrigin->canAccess(targetSecurityOrigin, reason)) + return true; + + return false; +} + +String Window::crossDomainAccessErrorMessage(const JSGlobalObject* other, SecurityOrigin::Reason) const +{ + const Frame* originFrame = static_cast<const Window*>(other)->impl()->frame(); + const Frame* targetFrame = impl()->frame(); + if (!originFrame || !targetFrame) + return String(); + WebCore::Document* targetDocument = targetFrame->document(); + WebCore::Document* originDocument = originFrame->document(); + if (!originDocument || !targetDocument) + return String(); + // FIXME: this error message should contain more specifics of why the same origin check has failed. + return String::format("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains, protocols and ports must match.\n", + targetDocument->url().string().utf8().data(), originDocument->url().string().utf8().data()); +} + +void Window::printErrorMessage(const String& message) const +{ + if (message.isEmpty()) + return; + + Frame* frame = impl()->frame(); + if (!frame) + return; + + if (frame->settings()->privateBrowsingEnabled()) + return; + + if (Interpreter::shouldPrintExceptions()) + printf("%s", message.utf8().data()); + + if (Page* page = frame->page()) + page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, message, 1, String()); // FIXME: provide a real line number and source URL. +} + +ExecState* Window::globalExec() +{ + // We need to make sure that any script execution happening in this + // frame does not destroy it + ASSERT(impl()->frame()); + impl()->frame()->keepAlive(); + return Base::globalExec(); +} + +bool Window::shouldInterruptScript() const +{ + ASSERT(impl()->frame()); + Page* page = impl()->frame()->page(); + + // See <rdar://problem/5479443>. We don't think that page can ever be NULL + // in this case, but if it is, we've gotten into a state where we may have + // hung the UI, with no way to ask the client whether to cancel execution. + // For now, our solution is just to cancel execution no matter what, + // ensuring that we never hang. We might want to consider other solutions + // if we discover problems with this one. + ASSERT(page); + if (!page) + return true; + + return page->chrome()->shouldInterruptJavaScript(); +} + +void Window::setListener(ExecState* exec, const AtomicString& eventType, JSValue* func) +{ + ASSERT(impl()->frame()); + Document* doc = impl()->frame()->document(); + if (!doc) + return; + + doc->setHTMLWindowEventListener(eventType, findOrCreateJSEventListener(func, true)); +} + +JSValue* Window::getListener(ExecState* exec, const AtomicString& eventType) const +{ + ASSERT(impl()->frame()); + Document* doc = impl()->frame()->document(); + if (!doc) + return jsUndefined(); + + WebCore::EventListener* listener = doc->getHTMLWindowEventListener(eventType); + if (listener && static_cast<JSEventListener*>(listener)->listenerObj()) + return static_cast<JSEventListener*>(listener)->listenerObj(); + return jsNull(); +} + +JSEventListener* Window::findJSEventListener(JSValue* val, bool html) +{ + if (!val->isObject()) + return 0; + JSObject* object = static_cast<JSObject*>(val); + ListenersMap& listeners = html ? d->jsHTMLEventListeners : d->jsEventListeners; + return listeners.get(object); +} + +JSEventListener* Window::findOrCreateJSEventListener(JSValue* val, bool html) +{ + JSEventListener* listener = findJSEventListener(val, html); + if (listener) + return listener; + + if (!val->isObject()) + return 0; + JSObject* object = static_cast<JSObject*>(val); + + // Note that the JSEventListener constructor adds it to our jsEventListeners list + return new JSEventListener(object, this, html); +} + +JSUnprotectedEventListener* Window::findJSUnprotectedEventListener(JSValue* val, bool html) +{ + if (!val->isObject()) + return 0; + JSObject* object = static_cast<JSObject*>(val); + UnprotectedListenersMap& listeners = html ? d->jsUnprotectedHTMLEventListeners : d->jsUnprotectedEventListeners; + return listeners.get(object); +} + +JSUnprotectedEventListener* Window::findOrCreateJSUnprotectedEventListener(JSValue* val, bool html) +{ + JSUnprotectedEventListener* listener = findJSUnprotectedEventListener(val, html); + if (listener) + return listener; + if (!val->isObject()) + return 0; + JSObject* object = static_cast<JSObject*>(val); + + // The JSUnprotectedEventListener constructor adds it to our jsUnprotectedEventListeners map. + return new JSUnprotectedEventListener(object, this, html); +} + +void Window::clearHelperObjectProperties() +{ + d->loc = 0; + d->m_evt = 0; +} + +void Window::clear() +{ + JSLock lock; + + if (d->m_returnValueSlot && !*d->m_returnValueSlot) + *d->m_returnValueSlot = getDirect("returnValue"); + + clearAllTimeouts(); + clearHelperObjectProperties(); + + // Now recreate a working global object for the next URL that will use us; but only if we haven't been + // disconnected yet + if (Frame* frame = impl()->frame()) + frame->scriptProxy()->globalObject()->reset(JSDOMWindowPrototype::self()); + + // there's likely to be lots of garbage now + gcController().garbageCollectSoon(); +} + +void Window::setCurrentEvent(Event* evt) +{ + d->m_evt = evt; +} + +Event* Window::currentEvent() +{ + return d->m_evt; +} + +JSValue* windowProtoFuncAToB(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&Window::info)) + return throwError(exec, TypeError); + if (!static_cast<Window*>(thisObj)->allowsAccessFrom(exec)) + return jsUndefined(); + + if (args.size() < 1) + return throwError(exec, SyntaxError, "Not enough arguments"); + + JSValue* v = args[0]; + if (v->isNull()) + return jsString(); + + UString s = v->toString(exec); + if (!s.is8Bit()) { + setDOMException(exec, INVALID_CHARACTER_ERR); + return jsUndefined(); + } + + Vector<char> in(s.size()); + for (int i = 0; i < s.size(); ++i) + in[i] = static_cast<char>(s.data()[i].unicode()); + Vector<char> out; + + if (!base64Decode(in, out)) + return throwError(exec, GeneralError, "Cannot decode base64"); + + return jsString(String(out.data(), out.size())); +} + +JSValue* windowProtoFuncBToA(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&Window::info)) + return throwError(exec, TypeError); + if (!static_cast<Window*>(thisObj)->allowsAccessFrom(exec)) + return jsUndefined(); + + if (args.size() < 1) + return throwError(exec, SyntaxError, "Not enough arguments"); + + JSValue* v = args[0]; + if (v->isNull()) + return jsString(); + + UString s = v->toString(exec); + if (!s.is8Bit()) { + setDOMException(exec, INVALID_CHARACTER_ERR); + return jsUndefined(); + } + + Vector<char> in(s.size()); + for (int i = 0; i < s.size(); ++i) + in[i] = static_cast<char>(s.data()[i].unicode()); + Vector<char> out; + + base64Encode(in, out); + + return jsString(String(out.data(), out.size())); +} + +JSValue* windowProtoFuncOpen(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&Window::info)) + return throwError(exec, TypeError); + Window* window = static_cast<Window*>(thisObj); + if (!window->allowsAccessFrom(exec)) + return jsUndefined(); + + Frame* frame = window->impl()->frame(); + if (!frame) + return jsUndefined(); + Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame(); + if (!activeFrame) + return jsUndefined(); + + Page* page = frame->page(); + + String urlString = valueToStringWithUndefinedOrNullCheck(exec, args[0]); + AtomicString frameName = args[1]->isUndefinedOrNull() ? "_blank" : AtomicString(args[1]->toString(exec)); + + // Because FrameTree::find() returns true for empty strings, we must check for empty framenames. + // Otherwise, illegitimate window.open() calls with no name will pass right through the popup blocker. + if (!allowPopUp(exec) && (frameName.isEmpty() || !frame->tree()->find(frameName))) + return jsUndefined(); + + // Get the target frame for the special cases of _top and _parent. In those + // cases, we can schedule a location change right now and return early. + bool topOrParent = false; + if (frameName == "_top") { + frame = frame->tree()->top(); + topOrParent = true; + } else if (frameName == "_parent") { + if (Frame* parent = frame->tree()->parent()) + frame = parent; + topOrParent = true; + } + if (topOrParent) { + if (!activeFrame->loader()->shouldAllowNavigation(frame)) + return jsUndefined(); + + String completedURL; + if (!urlString.isEmpty()) + completedURL = activeFrame->document()->completeURL(urlString).string(); + + const Window* targetedWindow = Window::retrieveWindow(frame); + if (!completedURL.isEmpty() && (!protocolIs(completedURL, "javascript") || (targetedWindow && targetedWindow->allowsAccessFrom(exec)))) { + bool userGesture = activeFrame->scriptProxy()->processingUserGesture(); + frame->loader()->scheduleLocationChange(completedURL, activeFrame->loader()->outgoingReferrer(), false, userGesture); + } + return Window::retrieve(frame); + } + + // In the case of a named frame or a new window, we'll use the createWindow() helper + WindowFeatures windowFeatures(valueToStringWithUndefinedOrNullCheck(exec, args[2])); + FloatRect windowRect(windowFeatures.x, windowFeatures.y, windowFeatures.width, windowFeatures.height); + WebCore::DOMWindow::adjustWindowRect(screenAvailableRect(page->mainFrame()->view()), windowRect, windowRect); + + windowFeatures.x = windowRect.x(); + windowFeatures.y = windowRect.y(); + windowFeatures.height = windowRect.height(); + windowFeatures.width = windowRect.width(); + + frame = createWindow(exec, frame, urlString, frameName, windowFeatures, 0); + + if (!frame) + return jsUndefined(); + + return Window::retrieve(frame); // global object +} + +JSValue* windowProtoFuncSetTimeout(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&Window::info)) + return throwError(exec, TypeError); + Window* window = static_cast<Window*>(thisObj); + if (!window->allowsAccessFrom(exec)) + return jsUndefined(); + + JSValue* v = args[0]; + if (v->isString()) + return jsNumber(window->installTimeout(v->toString(exec), args[1]->toInt32(exec), true /*single shot*/)); + if (v->isObject() && static_cast<JSObject*>(v)->implementsCall()) { + List argsTail; + args.getSlice(2, argsTail); + return jsNumber(window->installTimeout(v, argsTail, args[1]->toInt32(exec), true /*single shot*/)); + } + + return jsUndefined(); +} + +JSValue* windowProtoFuncClearTimeout(ExecState* exec, JSObject* thisObj, const List& args) +{ + // Also the implementation for window.clearInterval() + + if (!thisObj->inherits(&Window::info)) + return throwError(exec, TypeError); + Window* window = static_cast<Window*>(thisObj); + if (!window->allowsAccessFrom(exec)) + return jsUndefined(); + + window->clearTimeout(args[0]->toInt32(exec)); + return jsUndefined(); +} + +JSValue* windowProtoFuncSetInterval(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&Window::info)) + return throwError(exec, TypeError); + Window* window = static_cast<Window*>(thisObj); + if (!window->allowsAccessFrom(exec)) + return jsUndefined(); + + if (args.size() >= 2) { + JSValue* v = args[0]; + int delay = args[1]->toInt32(exec); + if (v->isString()) + return jsNumber(window->installTimeout(v->toString(exec), delay, false)); + if (v->isObject() && static_cast<JSObject*>(v)->implementsCall()) { + List argsTail; + args.getSlice(2, argsTail); + return jsNumber(window->installTimeout(v, argsTail, delay, false)); + } + } + + return jsUndefined(); + +} + +JSValue* windowProtoFuncAddEventListener(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&Window::info)) + return throwError(exec, TypeError); + Window* window = static_cast<Window*>(thisObj); + if (!window->allowsAccessFrom(exec)) + return jsUndefined(); + Frame* frame = window->impl()->frame(); + if (!frame) + return jsUndefined(); + + if (JSEventListener* listener = window->findOrCreateJSEventListener(args[1])) { + if (Document* doc = frame->document()) + doc->addWindowEventListener(AtomicString(args[0]->toString(exec)), listener, args[2]->toBoolean(exec)); + } + + return jsUndefined(); +} + +JSValue* windowProtoFuncRemoveEventListener(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&Window::info)) + return throwError(exec, TypeError); + Window* window = static_cast<Window*>(thisObj); + if (!window->allowsAccessFrom(exec)) + return jsUndefined(); + Frame* frame = window->impl()->frame(); + if (!frame) + return jsUndefined(); + + if (JSEventListener* listener = window->findJSEventListener(args[1])) { + if (Document* doc = frame->document()) + doc->removeWindowEventListener(AtomicString(args[0]->toString(exec)), listener, args[2]->toBoolean(exec)); + } + + return jsUndefined(); +} + +JSValue* windowProtoFuncShowModalDialog(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&Window::info)) + return throwError(exec, TypeError); + Window* window = static_cast<Window*>(thisObj); + Frame* frame = window->impl()->frame(); + if (!frame) + return jsUndefined(); + + return showModalDialog(exec, frame, valueToStringWithUndefinedOrNullCheck(exec, args[0]), args[1], valueToStringWithUndefinedOrNullCheck(exec, args[2])); +} + +JSValue* windowProtoFuncNotImplemented(ExecState* exec, JSObject* thisObj, const List& args) +{ + if (!thisObj->inherits(&Window::info)) + return throwError(exec, TypeError); + + return jsUndefined(); +} + +void Window::setReturnValueSlot(JSValue** slot) +{ + d->m_returnValueSlot = slot; +} + +////////////////////// timeouts //////////////////////// + +void Window::clearAllTimeouts() +{ + deleteAllValues(d->m_timeouts); + d->m_timeouts.clear(); +} + +int Window::installTimeout(WebCore::ScheduledAction* a, int t, bool singleShot) +{ + int timeoutId = ++lastUsedTimeoutId; + + // avoid wraparound going negative on us + if (timeoutId <= 0) + timeoutId = 1; + + int nestLevel = timerNestingLevel + 1; + DOMWindowTimer* timer = new DOMWindowTimer(timeoutId, nestLevel, this, a); + ASSERT(!d->m_timeouts.get(timeoutId)); + d->m_timeouts.set(timeoutId, timer); + // Use a minimum interval of 10 ms to match other browsers, but only once we've + // nested enough to notice that we're repeating. + // Faster timers might be "better", but they're incompatible. + double interval = max(0.001, t * 0.001); + if (interval < cMinimumTimerInterval && nestLevel >= cMaxTimerNestingLevel) + interval = cMinimumTimerInterval; + if (singleShot) + timer->startOneShot(interval); + else + timer->startRepeating(interval); + return timeoutId; +} + +int Window::installTimeout(const UString& handler, int t, bool singleShot) +{ + return installTimeout(new WebCore::ScheduledAction(handler), t, singleShot); +} + +int Window::installTimeout(JSValue* func, const List& args, int t, bool singleShot) +{ + return installTimeout(new WebCore::ScheduledAction(func, args), t, singleShot); +} + +WebCore::PausedTimeouts* Window::pauseTimeouts() +{ + size_t count = d->m_timeouts.size(); + if (count == 0) + return 0; + + PausedTimeout* t = new PausedTimeout [count]; + PausedTimeouts* result = new PausedTimeouts(t, count); + + WindowPrivate::TimeoutsMap::iterator it = d->m_timeouts.begin(); + for (size_t i = 0; i != count; ++i, ++it) { + int timeoutId = it->first; + DOMWindowTimer* timer = it->second; + t[i].timeoutId = timeoutId; + t[i].nestingLevel = timer->nestingLevel(); + t[i].nextFireInterval = timer->nextFireInterval(); + t[i].repeatInterval = timer->repeatInterval(); + t[i].action = timer->takeAction(); + } + ASSERT(it == d->m_timeouts.end()); + + deleteAllValues(d->m_timeouts); + d->m_timeouts.clear(); + + return result; +} + +void Window::resumeTimeouts(PausedTimeouts* timeouts) +{ + if (!timeouts) + return; + size_t count = timeouts->numTimeouts(); + PausedTimeout* array = timeouts->takeTimeouts(); + for (size_t i = 0; i != count; ++i) { + int timeoutId = array[i].timeoutId; + DOMWindowTimer* timer = new DOMWindowTimer(timeoutId, array[i].nestingLevel, this, array[i].action); + d->m_timeouts.set(timeoutId, timer); + timer->start(array[i].nextFireInterval, array[i].repeatInterval); + } + delete [] array; +} + +void Window::clearTimeout(int timeoutId, bool delAction) +{ + // timeout IDs have to be positive, and 0 and -1 are unsafe to + // even look up since they are the empty and deleted value + // respectively + if (timeoutId <= 0) + return; + + delete d->m_timeouts.take(timeoutId); +} + +void Window::timerFired(DOMWindowTimer* timer) +{ + // Simple case for non-one-shot timers. + if (timer->isActive()) { + int timeoutId = timer->timeoutId(); + + timer->action()->execute(this); + // The DOMWindowTimer object may have been deleted or replaced during execution, + // so we re-fetch it. + timer = d->m_timeouts.get(timeoutId); + if (!timer) + return; + + if (timer->repeatInterval() && timer->repeatInterval() < cMinimumTimerInterval) { + timer->setNestingLevel(timer->nestingLevel() + 1); + if (timer->nestingLevel() >= cMaxTimerNestingLevel) + timer->augmentRepeatInterval(cMinimumTimerInterval - timer->repeatInterval()); + } + return; + } + + // Delete timer before executing the action for one-shot timers. + WebCore::ScheduledAction* action = timer->takeAction(); + d->m_timeouts.remove(timer->timeoutId()); + delete timer; + action->execute(this); + + JSLock lock; + delete action; +} + +void Window::disconnectFrame() +{ + clearAllTimeouts(); + if (d->loc) + d->loc->m_frame = 0; +} + +Window::ListenersMap& Window::jsEventListeners() +{ + return d->jsEventListeners; +} + +Window::ListenersMap& Window::jsHTMLEventListeners() +{ + return d->jsHTMLEventListeners; +} + +Window::UnprotectedListenersMap& Window::jsUnprotectedEventListeners() +{ + return d->jsUnprotectedEventListeners; +} + +Window::UnprotectedListenersMap& Window::jsUnprotectedHTMLEventListeners() +{ + return d->jsUnprotectedHTMLEventListeners; +} + +///////////////////////////////////////////////////////////////////////////// + +void DOMWindowTimer::fired() +{ + timerNestingLevel = m_nestingLevel; + m_object->timerFired(this); + timerNestingLevel = 0; +} + +} // namespace KJS + +using namespace KJS; + +namespace WebCore { + +JSValue* toJS(ExecState*, DOMWindow* domWindow) +{ + if (!domWindow) + return jsNull(); + Frame* frame = domWindow->frame(); + if (!frame) + return jsNull(); + return Window::retrieve(frame); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/kjs_window.h b/WebCore/bindings/js/kjs_window.h new file mode 100644 index 0000000..ad415aa --- /dev/null +++ b/WebCore/bindings/js/kjs_window.h @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2000 Harri Porten (porten@kde.org) + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reseved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef kjs_window_h +#define kjs_window_h + +#include "PlatformString.h" +#include "kjs_binding.h" +#include <kjs/protect.h> +#include "SecurityOrigin.h" +#include <wtf/HashMap.h> +#include <wtf/Noncopyable.h> +#include <wtf/OwnPtr.h> + +namespace WebCore { + class AtomicString; + class DOMWindow; + class Frame; + class JSEventListener; + class JSLocation; + class JSUnprotectedEventListener; + class PausedTimeouts; + class ScheduledAction; +} + +namespace KJS { + + class DOMWindowTimer; + class WindowPrivate; + + // This is the only WebCore JS binding which does not inherit from DOMObject + class Window : public JSGlobalObject { + typedef JSGlobalObject Base; + + friend class WebCore::ScheduledAction; + protected: + Window(JSObject* prototype, WebCore::DOMWindow*); + + public: + virtual ~Window(); + + WebCore::DOMWindow* impl() const { return m_impl.get(); } + + void disconnectFrame(); + + // Returns and registers a window object. In case there's already a Window + // for the specified frame p this will be returned in order to have unique + // bindings. + static JSValue* retrieve(WebCore::Frame*); + + // Returns the Window object for a given HTML frame + static Window* retrieveWindow(WebCore::Frame*); + + // Returns a pointer to the Window object this javascript interpreting instance + // was called from. + static Window* retrieveActive(ExecState*); + + virtual void mark(); + + virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); + JSValue* getValueProperty(ExecState*, int token) const; + virtual void put(ExecState*, const Identifier& propertyName, JSValue*); + + int installTimeout(const UString& handler, int t, bool singleShot); + int installTimeout(JSValue* function, const List& args, int t, bool singleShot); + void clearTimeout(int timerId, bool delAction = true); + WebCore::PausedTimeouts* pauseTimeouts(); + void resumeTimeouts(WebCore::PausedTimeouts*); + + void timerFired(DOMWindowTimer*); + + WebCore::JSLocation* location() const; + + // Finds a wrapper of a JS EventListener, returns 0 if no existing one. + WebCore::JSEventListener* findJSEventListener(JSValue*, bool html = false); + + // Finds or creates a wrapper of a JS EventListener. JS EventListener object is GC-protected. + WebCore::JSEventListener *findOrCreateJSEventListener(JSValue*, bool html = false); + + // Finds a wrapper of a GC-unprotected JS EventListener, returns 0 if no existing one. + WebCore::JSUnprotectedEventListener* findJSUnprotectedEventListener(JSValue*, bool html = false); + + // Finds or creates a wrapper of a JS EventListener. JS EventListener object is *NOT* GC-protected. + WebCore::JSUnprotectedEventListener *findOrCreateJSUnprotectedEventListener(JSValue*, bool html = false); + + void clear(); + + void setCurrentEvent(WebCore::Event*); + WebCore::Event* currentEvent(); + + // Set a place to put a dialog return value when the window is cleared. + void setReturnValueSlot(JSValue** slot); + + typedef HashMap<JSObject*, WebCore::JSEventListener*> ListenersMap; + typedef HashMap<JSObject*, WebCore::JSUnprotectedEventListener*> UnprotectedListenersMap; + + ListenersMap& jsEventListeners(); + ListenersMap& jsHTMLEventListeners(); + UnprotectedListenersMap& jsUnprotectedEventListeners(); + UnprotectedListenersMap& jsUnprotectedHTMLEventListeners(); + + virtual const ClassInfo* classInfo() const { return &info; } + static const ClassInfo info; + + virtual ExecState* globalExec(); + + virtual bool shouldInterruptScript() const; + + bool allowsAccessFrom(ExecState*) const; + bool allowsAccessFromNoErrorMessage(ExecState*) const; + bool allowsAccessFrom(ExecState*, WebCore::String& message) const; + + void printErrorMessage(const WebCore::String&) const; + + // Don't call this version of allowsAccessFrom -- it's a slightly incorrect implementation used only by WebScriptObject + virtual bool allowsAccessFrom(const JSGlobalObject*) const; + + enum { + // Attributes + Crypto, Event_, Location_, Navigator_, + ClientInformation, + + // Event Listeners + Onabort, Onblur, Onchange, Onclick, + Ondblclick, Onerror, Onfocus, Onkeydown, + Onkeypress, Onkeyup, Onload, Onmousedown, + Onmousemove, Onmouseout, Onmouseover, Onmouseup, + OnWindowMouseWheel, Onreset, Onresize, Onscroll, + Onsearch, Onselect, Onsubmit, Onunload, + Onbeforeunload, + + // Constructors + DOMException, Audio, Image, Option, XMLHttpRequest, + XSLTProcessor_ + }; + + private: + JSValue* getListener(ExecState*, const WebCore::AtomicString& eventType) const; + void setListener(ExecState*, const WebCore::AtomicString& eventType, JSValue* func); + + static JSValue* childFrameGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&); + static JSValue* indexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&); + static JSValue* namedItemGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&); + + void clearHelperObjectProperties(); + void clearAllTimeouts(); + int installTimeout(WebCore::ScheduledAction*, int interval, bool singleShot); + + bool allowsAccessFromPrivate(const JSGlobalObject*, WebCore::SecurityOrigin::Reason&) const; + bool allowsAccessFromPrivate(const ExecState*, WebCore::SecurityOrigin::Reason&) const; + WebCore::String crossDomainAccessErrorMessage(const JSGlobalObject*, WebCore::SecurityOrigin::Reason) const; + + RefPtr<WebCore::DOMWindow> m_impl; + OwnPtr<WindowPrivate> d; + }; + + // Functions + JSValue* windowProtoFuncAToB(ExecState*, JSObject*, const List&); + JSValue* windowProtoFuncBToA(ExecState*, JSObject*, const List&); + JSValue* windowProtoFuncOpen(ExecState*, JSObject*, const List&); + JSValue* windowProtoFuncSetTimeout(ExecState*, JSObject*, const List&); + JSValue* windowProtoFuncClearTimeout(ExecState*, JSObject*, const List&); + JSValue* windowProtoFuncSetInterval(ExecState*, JSObject*, const List&); + JSValue* windowProtoFuncAddEventListener(ExecState*, JSObject*, const List&); + JSValue* windowProtoFuncRemoveEventListener(ExecState*, JSObject*, const List&); + JSValue* windowProtoFuncShowModalDialog(ExecState*, JSObject*, const List&); + JSValue* windowProtoFuncNotImplemented(ExecState*, JSObject*, const List&); + +} // namespace KJS + +namespace WebCore { + KJS::JSValue* toJS(KJS::ExecState*, DOMWindow*); +} // namespace WebCore + +#endif // kjs_window_h |