diff options
Diffstat (limited to 'WebCore/bindings')
238 files changed, 7771 insertions, 4268 deletions
diff --git a/WebCore/bindings/js/GCController.cpp b/WebCore/bindings/js/GCController.cpp index ceb7928..db295c2 100644 --- a/WebCore/bindings/js/GCController.cpp +++ b/WebCore/bindings/js/GCController.cpp @@ -65,7 +65,7 @@ GCController::GCController() void GCController::garbageCollectSoon() { if (!m_GCTimer.isActive()) - m_GCTimer.startOneShot(0); + m_GCTimer.startOneShot(0.5); } void GCController::gcTimerFired(Timer<GCController>*) diff --git a/WebCore/bindings/js/JSAttrCustom.cpp b/WebCore/bindings/js/JSAttrCustom.cpp index a97d039..4f3c8ee 100644 --- a/WebCore/bindings/js/JSAttrCustom.cpp +++ b/WebCore/bindings/js/JSAttrCustom.cpp @@ -40,14 +40,14 @@ namespace WebCore { using namespace HTMLNames; -void JSAttr::setValue(ExecState* exec, JSValuePtr value) +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 (equalIgnoringCase(imp->name(), "src") && protocolIsJavaScript(parseURL(attrValue))) { if (!checkNodeSecurity(exec, static_cast<HTMLFrameElementBase*>(ownerElement)->contentDocument())) return; } diff --git a/WebCore/bindings/js/JSAudioConstructor.cpp b/WebCore/bindings/js/JSAudioConstructor.cpp index 3fd53fe..74bcad5 100644 --- a/WebCore/bindings/js/JSAudioConstructor.cpp +++ b/WebCore/bindings/js/JSAudioConstructor.cpp @@ -41,13 +41,14 @@ namespace WebCore { const ClassInfo JSAudioConstructor::s_info = { "AudioConstructor", 0, 0, 0 }; -JSAudioConstructor::JSAudioConstructor(ExecState* exec, ScriptExecutionContext* context) +JSAudioConstructor::JSAudioConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) : DOMObject(JSAudioConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) - , m_globalObject(toJSDOMGlobalObject(context)) + , m_globalObject(globalObject) { - ASSERT(context->isDocument()); + ASSERT(globalObject->scriptExecutionContext()); + ASSERT(globalObject->scriptExecutionContext()->isDocument()); - putDirect(exec->propertyNames().prototype, JSHTMLAudioElementPrototype::self(exec), None); + putDirect(exec->propertyNames().prototype, JSHTMLAudioElementPrototype::self(exec, exec->lexicalGlobalObject()), None); putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum); } @@ -60,9 +61,13 @@ static JSObject* constructAudio(ExecState* exec, JSObject* constructor, const Ar { // FIXME: Why doesn't this need the call toJS on the document like JSImageConstructor? - RefPtr<HTMLAudioElement> audio = new HTMLAudioElement(HTMLNames::audioTag, static_cast<JSAudioConstructor*>(constructor)->document()); + Document* document = static_cast<JSAudioConstructor*>(constructor)->document(); + if (!document) + return throwError(exec, ReferenceError, "Audio constructor associated document is unavailable"); + + RefPtr<HTMLAudioElement> audio = new HTMLAudioElement(HTMLNames::audioTag, document); if (args.size() > 0) { - audio->setSrc(args.at(exec, 0).toString(exec)); + audio->setSrc(args.at(0).toString(exec)); audio->scheduleLoad(); } return asObject(toJS(exec, audio.release())); diff --git a/WebCore/bindings/js/JSAudioConstructor.h b/WebCore/bindings/js/JSAudioConstructor.h index 1078b0f..0a3a7ea 100644 --- a/WebCore/bindings/js/JSAudioConstructor.h +++ b/WebCore/bindings/js/JSAudioConstructor.h @@ -36,7 +36,7 @@ namespace WebCore { class JSAudioConstructor : public DOMObject { public: - JSAudioConstructor(JSC::ExecState*, ScriptExecutionContext*); + JSAudioConstructor(JSC::ExecState*, JSDOMGlobalObject*); Document* document() const; diff --git a/WebCore/bindings/js/JSCDATASectionCustom.cpp b/WebCore/bindings/js/JSCDATASectionCustom.cpp index 68180f1..44a8957 100644 --- a/WebCore/bindings/js/JSCDATASectionCustom.cpp +++ b/WebCore/bindings/js/JSCDATASectionCustom.cpp @@ -32,7 +32,7 @@ using namespace JSC; namespace WebCore { -JSValuePtr toJSNewlyCreated(ExecState* exec, CDATASection* section) +JSValue toJSNewlyCreated(ExecState* exec, CDATASection* section) { if (!section) return jsNull(); diff --git a/WebCore/bindings/js/JSCSSRuleCustom.cpp b/WebCore/bindings/js/JSCSSRuleCustom.cpp index 32462fa..2c20431 100644 --- a/WebCore/bindings/js/JSCSSRuleCustom.cpp +++ b/WebCore/bindings/js/JSCSSRuleCustom.cpp @@ -49,7 +49,7 @@ using namespace JSC; namespace WebCore { -JSValuePtr toJS(ExecState* exec, CSSRule* rule) +JSValue toJS(ExecState* exec, CSSRule* rule) { if (!rule) return jsNull(); diff --git a/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp b/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp index 22154ce..b07f201 100644 --- a/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp +++ b/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp @@ -127,7 +127,7 @@ bool JSCSSStyleDeclaration::canGetItemsForName(ExecState*, CSSStyleDeclaration*, // FIXME: You can get these properties, and set them (see customPut below), // but you should also be able to enumerate them. -JSValuePtr JSCSSStyleDeclaration::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSCSSStyleDeclaration::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { JSCSSStyleDeclaration* thisObj = static_cast<JSCSSStyleDeclaration*>(asObject(slot.slotBase())); @@ -156,7 +156,7 @@ JSValuePtr JSCSSStyleDeclaration::nameGetter(ExecState* exec, const Identifier& } -bool JSCSSStyleDeclaration::customPut(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot&) +bool JSCSSStyleDeclaration::customPut(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot&) { if (!isCSSPropertyName(propertyName)) return false; diff --git a/WebCore/bindings/js/JSCSSValueCustom.cpp b/WebCore/bindings/js/JSCSSValueCustom.cpp index 9e31304..ad0cee1 100644 --- a/WebCore/bindings/js/JSCSSValueCustom.cpp +++ b/WebCore/bindings/js/JSCSSValueCustom.cpp @@ -44,7 +44,7 @@ using namespace JSC; namespace WebCore { -JSValuePtr toJS(ExecState* exec, CSSValue* value) +JSValue toJS(ExecState* exec, CSSValue* value) { if (!value) return jsNull(); diff --git a/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp b/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp index ae48440..76db871 100644 --- a/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp +++ b/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp @@ -40,7 +40,7 @@ using namespace JSC; namespace WebCore { -static JSValuePtr toJS(ExecState* exec, CanvasStyle* style) +static JSValue toJS(ExecState* exec, CanvasStyle* style) { if (style->canvasGradient()) return toJS(exec, style->canvasGradient()); @@ -49,7 +49,7 @@ static JSValuePtr toJS(ExecState* exec, CanvasStyle* style) return jsString(exec, style->color()); } -static PassRefPtr<CanvasStyle> toHTMLCanvasStyle(ExecState*, JSValuePtr value) +static PassRefPtr<CanvasStyle> toHTMLCanvasStyle(ExecState*, JSValue value) { if (value.isString()) return CanvasStyle::create(asString(value)->value()); @@ -63,27 +63,27 @@ static PassRefPtr<CanvasStyle> toHTMLCanvasStyle(ExecState*, JSValuePtr value) return 0; } -JSValuePtr JSCanvasRenderingContext2D::strokeStyle(ExecState* exec) const +JSValue JSCanvasRenderingContext2D::strokeStyle(ExecState* exec) const { return toJS(exec, impl()->strokeStyle()); } -void JSCanvasRenderingContext2D::setStrokeStyle(ExecState* exec, JSValuePtr value) +void JSCanvasRenderingContext2D::setStrokeStyle(ExecState* exec, JSValue value) { impl()->setStrokeStyle(toHTMLCanvasStyle(exec, value)); } -JSValuePtr JSCanvasRenderingContext2D::fillStyle(ExecState* exec) const +JSValue JSCanvasRenderingContext2D::fillStyle(ExecState* exec) const { return toJS(exec, impl()->fillStyle()); } -void JSCanvasRenderingContext2D::setFillStyle(ExecState* exec, JSValuePtr value) +void JSCanvasRenderingContext2D::setFillStyle(ExecState* exec, JSValue value) { impl()->setFillStyle(toHTMLCanvasStyle(exec, value)); } -JSValuePtr JSCanvasRenderingContext2D::setFillColor(ExecState* exec, const ArgList& args) +JSValue JSCanvasRenderingContext2D::setFillColor(ExecState* exec, const ArgList& args) { CanvasRenderingContext2D* context = impl(); @@ -95,24 +95,24 @@ JSValuePtr JSCanvasRenderingContext2D::setFillColor(ExecState* exec, const ArgLi // 5 args = c, m, y, k, a switch (args.size()) { case 1: - if (args.at(exec, 0).isString()) - context->setFillColor(asString(args.at(exec, 0))->value()); + if (args.at(0).isString()) + context->setFillColor(asString(args.at(0))->value()); else - context->setFillColor(args.at(exec, 0).toFloat(exec)); + context->setFillColor(args.at(0).toFloat(exec)); break; case 2: - if (args.at(exec, 0).isString()) - context->setFillColor(asString(args.at(exec, 0))->value(), args.at(exec, 1).toFloat(exec)); + if (args.at(0).isString()) + context->setFillColor(asString(args.at(0))->value(), args.at(1).toFloat(exec)); else - context->setFillColor(args.at(exec, 0).toFloat(exec), args.at(exec, 1).toFloat(exec)); + context->setFillColor(args.at(0).toFloat(exec), args.at(1).toFloat(exec)); break; case 4: - context->setFillColor(args.at(exec, 0).toFloat(exec), args.at(exec, 1).toFloat(exec), - args.at(exec, 2).toFloat(exec), args.at(exec, 3).toFloat(exec)); + context->setFillColor(args.at(0).toFloat(exec), args.at(1).toFloat(exec), + args.at(2).toFloat(exec), args.at(3).toFloat(exec)); break; case 5: - context->setFillColor(args.at(exec, 0).toFloat(exec), args.at(exec, 1).toFloat(exec), - args.at(exec, 2).toFloat(exec), args.at(exec, 3).toFloat(exec), args.at(exec, 4).toFloat(exec)); + context->setFillColor(args.at(0).toFloat(exec), args.at(1).toFloat(exec), + args.at(2).toFloat(exec), args.at(3).toFloat(exec), args.at(4).toFloat(exec)); break; default: return throwError(exec, SyntaxError); @@ -120,7 +120,7 @@ JSValuePtr JSCanvasRenderingContext2D::setFillColor(ExecState* exec, const ArgLi return jsUndefined(); } -JSValuePtr JSCanvasRenderingContext2D::setStrokeColor(ExecState* exec, const ArgList& args) +JSValue JSCanvasRenderingContext2D::setStrokeColor(ExecState* exec, const ArgList& args) { CanvasRenderingContext2D* context = impl(); @@ -132,24 +132,24 @@ JSValuePtr JSCanvasRenderingContext2D::setStrokeColor(ExecState* exec, const Arg // 5 args = c, m, y, k, a switch (args.size()) { case 1: - if (args.at(exec, 0).isString()) - context->setStrokeColor(asString(args.at(exec, 0))->value()); + if (args.at(0).isString()) + context->setStrokeColor(asString(args.at(0))->value()); else - context->setStrokeColor(args.at(exec, 0).toFloat(exec)); + context->setStrokeColor(args.at(0).toFloat(exec)); break; case 2: - if (args.at(exec, 0).isString()) - context->setStrokeColor(asString(args.at(exec, 0))->value(), args.at(exec, 1).toFloat(exec)); + if (args.at(0).isString()) + context->setStrokeColor(asString(args.at(0))->value(), args.at(1).toFloat(exec)); else - context->setStrokeColor(args.at(exec, 0).toFloat(exec), args.at(exec, 1).toFloat(exec)); + context->setStrokeColor(args.at(0).toFloat(exec), args.at(1).toFloat(exec)); break; case 4: - context->setStrokeColor(args.at(exec, 0).toFloat(exec), args.at(exec, 1).toFloat(exec), - args.at(exec, 2).toFloat(exec), args.at(exec, 3).toFloat(exec)); + context->setStrokeColor(args.at(0).toFloat(exec), args.at(1).toFloat(exec), + args.at(2).toFloat(exec), args.at(3).toFloat(exec)); break; case 5: - context->setStrokeColor(args.at(exec, 0).toFloat(exec), args.at(exec, 1).toFloat(exec), - args.at(exec, 2).toFloat(exec), args.at(exec, 3).toFloat(exec), args.at(exec, 4).toFloat(exec)); + context->setStrokeColor(args.at(0).toFloat(exec), args.at(1).toFloat(exec), + args.at(2).toFloat(exec), args.at(3).toFloat(exec), args.at(4).toFloat(exec)); break; default: return throwError(exec, SyntaxError); @@ -158,21 +158,21 @@ JSValuePtr JSCanvasRenderingContext2D::setStrokeColor(ExecState* exec, const Arg return jsUndefined(); } -JSValuePtr JSCanvasRenderingContext2D::strokeRect(ExecState* exec, const ArgList& args) +JSValue JSCanvasRenderingContext2D::strokeRect(ExecState* exec, const ArgList& args) { CanvasRenderingContext2D* context = impl(); if (args.size() <= 4) - context->strokeRect(args.at(exec, 0).toFloat(exec), args.at(exec, 1).toFloat(exec), - args.at(exec, 2).toFloat(exec), args.at(exec, 3).toFloat(exec)); + context->strokeRect(args.at(0).toFloat(exec), args.at(1).toFloat(exec), + args.at(2).toFloat(exec), args.at(3).toFloat(exec)); else - context->strokeRect(args.at(exec, 0).toFloat(exec), args.at(exec, 1).toFloat(exec), - args.at(exec, 2).toFloat(exec), args.at(exec, 3).toFloat(exec), args.at(exec, 4).toFloat(exec)); + context->strokeRect(args.at(0).toFloat(exec), args.at(1).toFloat(exec), + args.at(2).toFloat(exec), args.at(3).toFloat(exec), args.at(4).toFloat(exec)); return jsUndefined(); } -JSValuePtr JSCanvasRenderingContext2D::drawImage(ExecState* exec, const ArgList& args) +JSValue JSCanvasRenderingContext2D::drawImage(ExecState* exec, const ArgList& args) { CanvasRenderingContext2D* context = impl(); @@ -182,7 +182,7 @@ JSValuePtr JSCanvasRenderingContext2D::drawImage(ExecState* exec, const ArgList& // 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. - JSValuePtr value = args.at(exec, 0); + JSValue value = args.at(0); if (!value.isObject()) return throwError(exec, TypeError); JSObject* o = asObject(value); @@ -192,18 +192,18 @@ JSValuePtr JSCanvasRenderingContext2D::drawImage(ExecState* exec, const ArgList& HTMLImageElement* imgElt = static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(o)->impl()); switch (args.size()) { case 3: - context->drawImage(imgElt, args.at(exec, 1).toFloat(exec), args.at(exec, 2).toFloat(exec)); + context->drawImage(imgElt, args.at(1).toFloat(exec), args.at(2).toFloat(exec)); break; case 5: - context->drawImage(imgElt, args.at(exec, 1).toFloat(exec), args.at(exec, 2).toFloat(exec), - args.at(exec, 3).toFloat(exec), args.at(exec, 4).toFloat(exec), ec); + context->drawImage(imgElt, args.at(1).toFloat(exec), args.at(2).toFloat(exec), + args.at(3).toFloat(exec), args.at(4).toFloat(exec), ec); setDOMException(exec, ec); break; case 9: - context->drawImage(imgElt, FloatRect(args.at(exec, 1).toFloat(exec), args.at(exec, 2).toFloat(exec), - args.at(exec, 3).toFloat(exec), args.at(exec, 4).toFloat(exec)), - FloatRect(args.at(exec, 5).toFloat(exec), args.at(exec, 6).toFloat(exec), - args.at(exec, 7).toFloat(exec), args.at(exec, 8).toFloat(exec)), ec); + context->drawImage(imgElt, FloatRect(args.at(1).toFloat(exec), args.at(2).toFloat(exec), + args.at(3).toFloat(exec), args.at(4).toFloat(exec)), + FloatRect(args.at(5).toFloat(exec), args.at(6).toFloat(exec), + args.at(7).toFloat(exec), args.at(8).toFloat(exec)), ec); setDOMException(exec, ec); break; default: @@ -213,18 +213,18 @@ JSValuePtr JSCanvasRenderingContext2D::drawImage(ExecState* exec, const ArgList& HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLElement*>(o)->impl()); switch (args.size()) { case 3: - context->drawImage(canvas, args.at(exec, 1).toFloat(exec), args.at(exec, 2).toFloat(exec)); + context->drawImage(canvas, args.at(1).toFloat(exec), args.at(2).toFloat(exec)); break; case 5: - context->drawImage(canvas, args.at(exec, 1).toFloat(exec), args.at(exec, 2).toFloat(exec), - args.at(exec, 3).toFloat(exec), args.at(exec, 4).toFloat(exec), ec); + context->drawImage(canvas, args.at(1).toFloat(exec), args.at(2).toFloat(exec), + args.at(3).toFloat(exec), args.at(4).toFloat(exec), ec); setDOMException(exec, ec); break; case 9: - context->drawImage(canvas, FloatRect(args.at(exec, 1).toFloat(exec), args.at(exec, 2).toFloat(exec), - args.at(exec, 3).toFloat(exec), args.at(exec, 4).toFloat(exec)), - FloatRect(args.at(exec, 5).toFloat(exec), args.at(exec, 6).toFloat(exec), - args.at(exec, 7).toFloat(exec), args.at(exec, 8).toFloat(exec)), ec); + context->drawImage(canvas, FloatRect(args.at(1).toFloat(exec), args.at(2).toFloat(exec), + args.at(3).toFloat(exec), args.at(4).toFloat(exec)), + FloatRect(args.at(5).toFloat(exec), args.at(6).toFloat(exec), + args.at(7).toFloat(exec), args.at(8).toFloat(exec)), ec); setDOMException(exec, ec); break; default: @@ -237,11 +237,11 @@ JSValuePtr JSCanvasRenderingContext2D::drawImage(ExecState* exec, const ArgList& return jsUndefined(); } -JSValuePtr JSCanvasRenderingContext2D::drawImageFromRect(ExecState* exec, const ArgList& args) +JSValue JSCanvasRenderingContext2D::drawImageFromRect(ExecState* exec, const ArgList& args) { CanvasRenderingContext2D* context = impl(); - JSValuePtr value = args.at(exec, 0); + JSValue value = args.at(0); if (!value.isObject()) return throwError(exec, TypeError); JSObject* o = asObject(value); @@ -249,52 +249,52 @@ JSValuePtr JSCanvasRenderingContext2D::drawImageFromRect(ExecState* exec, const if (!o->inherits(&JSHTMLImageElement::s_info)) return throwError(exec, TypeError); context->drawImageFromRect(static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(o)->impl()), - args.at(exec, 1).toFloat(exec), args.at(exec, 2).toFloat(exec), - args.at(exec, 3).toFloat(exec), args.at(exec, 4).toFloat(exec), - args.at(exec, 5).toFloat(exec), args.at(exec, 6).toFloat(exec), - args.at(exec, 7).toFloat(exec), args.at(exec, 8).toFloat(exec), - args.at(exec, 9).toString(exec)); + args.at(1).toFloat(exec), args.at(2).toFloat(exec), + args.at(3).toFloat(exec), args.at(4).toFloat(exec), + args.at(5).toFloat(exec), args.at(6).toFloat(exec), + args.at(7).toFloat(exec), args.at(8).toFloat(exec), + args.at(9).toString(exec)); return jsUndefined(); } -JSValuePtr JSCanvasRenderingContext2D::setShadow(ExecState* exec, const ArgList& args) +JSValue JSCanvasRenderingContext2D::setShadow(ExecState* exec, const ArgList& args) { CanvasRenderingContext2D* context = impl(); switch (args.size()) { case 3: - context->setShadow(args.at(exec, 0).toFloat(exec), args.at(exec, 1).toFloat(exec), - args.at(exec, 2).toFloat(exec)); + context->setShadow(args.at(0).toFloat(exec), args.at(1).toFloat(exec), + args.at(2).toFloat(exec)); break; case 4: - if (args.at(exec, 3).isString()) - context->setShadow(args.at(exec, 0).toFloat(exec), args.at(exec, 1).toFloat(exec), - args.at(exec, 2).toFloat(exec), asString(args.at(exec, 3))->value()); + if (args.at(3).isString()) + context->setShadow(args.at(0).toFloat(exec), args.at(1).toFloat(exec), + args.at(2).toFloat(exec), asString(args.at(3))->value()); else - context->setShadow(args.at(exec, 0).toFloat(exec), args.at(exec, 1).toFloat(exec), - args.at(exec, 2).toFloat(exec), args.at(exec, 3).toFloat(exec)); + context->setShadow(args.at(0).toFloat(exec), args.at(1).toFloat(exec), + args.at(2).toFloat(exec), args.at(3).toFloat(exec)); break; case 5: - if (args.at(exec, 3).isString()) - context->setShadow(args.at(exec, 0).toFloat(exec), args.at(exec, 1).toFloat(exec), - args.at(exec, 2).toFloat(exec), asString(args.at(exec, 3))->value(), - args.at(exec, 4).toFloat(exec)); + if (args.at(3).isString()) + context->setShadow(args.at(0).toFloat(exec), args.at(1).toFloat(exec), + args.at(2).toFloat(exec), asString(args.at(3))->value(), + args.at(4).toFloat(exec)); else - context->setShadow(args.at(exec, 0).toFloat(exec), args.at(exec, 1).toFloat(exec), - args.at(exec, 2).toFloat(exec), args.at(exec, 3).toFloat(exec), - args.at(exec, 4).toFloat(exec)); + context->setShadow(args.at(0).toFloat(exec), args.at(1).toFloat(exec), + args.at(2).toFloat(exec), args.at(3).toFloat(exec), + args.at(4).toFloat(exec)); break; case 7: - context->setShadow(args.at(exec, 0).toFloat(exec), args.at(exec, 1).toFloat(exec), - args.at(exec, 2).toFloat(exec), args.at(exec, 3).toFloat(exec), - args.at(exec, 4).toFloat(exec), args.at(exec, 5).toFloat(exec), - args.at(exec, 6).toFloat(exec)); + context->setShadow(args.at(0).toFloat(exec), args.at(1).toFloat(exec), + args.at(2).toFloat(exec), args.at(3).toFloat(exec), + args.at(4).toFloat(exec), args.at(5).toFloat(exec), + args.at(6).toFloat(exec)); break; case 8: - context->setShadow(args.at(exec, 0).toFloat(exec), args.at(exec, 1).toFloat(exec), - args.at(exec, 2).toFloat(exec), args.at(exec, 3).toFloat(exec), - args.at(exec, 4).toFloat(exec), args.at(exec, 5).toFloat(exec), - args.at(exec, 6).toFloat(exec), args.at(exec, 7).toFloat(exec)); + context->setShadow(args.at(0).toFloat(exec), args.at(1).toFloat(exec), + args.at(2).toFloat(exec), args.at(3).toFloat(exec), + args.at(4).toFloat(exec), args.at(5).toFloat(exec), + args.at(6).toFloat(exec), args.at(7).toFloat(exec)); break; default: return throwError(exec, SyntaxError); @@ -303,28 +303,28 @@ JSValuePtr JSCanvasRenderingContext2D::setShadow(ExecState* exec, const ArgList& return jsUndefined(); } -JSValuePtr JSCanvasRenderingContext2D::createPattern(ExecState* exec, const ArgList& args) +JSValue JSCanvasRenderingContext2D::createPattern(ExecState* exec, const ArgList& args) { CanvasRenderingContext2D* context = impl(); - JSValuePtr value = args.at(exec, 0); + JSValue value = args.at(0); if (!value.isObject()) return throwError(exec, TypeError); JSObject* o = asObject(value); if (o->inherits(&JSHTMLImageElement::s_info)) { ExceptionCode ec; - JSValuePtr pattern = toJS(exec, + JSValue pattern = toJS(exec, context->createPattern(static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(o)->impl()), - valueToStringWithNullCheck(exec, args.at(exec, 1)), ec).get()); + valueToStringWithNullCheck(exec, args.at(1)), ec).get()); setDOMException(exec, ec); return pattern; } if (o->inherits(&JSHTMLCanvasElement::s_info)) { ExceptionCode ec; - JSValuePtr pattern = toJS(exec, + JSValue pattern = toJS(exec, context->createPattern(static_cast<HTMLCanvasElement*>(static_cast<JSHTMLElement*>(o)->impl()), - valueToStringWithNullCheck(exec, args.at(exec, 1)), ec).get()); + valueToStringWithNullCheck(exec, args.at(1)), ec).get()); setDOMException(exec, ec); return pattern; } @@ -332,7 +332,7 @@ JSValuePtr JSCanvasRenderingContext2D::createPattern(ExecState* exec, const ArgL return jsUndefined(); } -JSValuePtr JSCanvasRenderingContext2D::putImageData(ExecState* exec, const ArgList& args) +JSValue JSCanvasRenderingContext2D::putImageData(ExecState* exec, const ArgList& args) { // putImageData has two variants // putImageData(ImageData, x, y) @@ -341,16 +341,16 @@ JSValuePtr JSCanvasRenderingContext2D::putImageData(ExecState* exec, const ArgLi ExceptionCode ec = 0; if (args.size() >= 7) - context->putImageData(toImageData(args.at(exec, 0)), args.at(exec, 1).toFloat(exec), args.at(exec, 2).toFloat(exec), - args.at(exec, 3).toFloat(exec), args.at(exec, 4).toFloat(exec), args.at(exec, 5).toFloat(exec), args.at(exec, 6).toFloat(exec), ec); + context->putImageData(toImageData(args.at(0)), args.at(1).toFloat(exec), args.at(2).toFloat(exec), + args.at(3).toFloat(exec), args.at(4).toFloat(exec), args.at(5).toFloat(exec), args.at(6).toFloat(exec), ec); else - context->putImageData(toImageData(args.at(exec, 0)), args.at(exec, 1).toFloat(exec), args.at(exec, 2).toFloat(exec), ec); + context->putImageData(toImageData(args.at(0)), args.at(1).toFloat(exec), args.at(2).toFloat(exec), ec); setDOMException(exec, ec); return jsUndefined(); } -JSValuePtr JSCanvasRenderingContext2D::fillText(ExecState* exec, const ArgList& args) +JSValue JSCanvasRenderingContext2D::fillText(ExecState* exec, const ArgList& args) { CanvasRenderingContext2D* context = impl(); @@ -362,13 +362,13 @@ JSValuePtr JSCanvasRenderingContext2D::fillText(ExecState* exec, const ArgList& return throwError(exec, SyntaxError); if (args.size() == 4) - context->fillText(args.at(exec, 0).toString(exec), args.at(exec, 1).toFloat(exec), args.at(exec, 2).toFloat(exec), args.at(exec, 3).toFloat(exec)); + context->fillText(args.at(0).toString(exec), args.at(1).toFloat(exec), args.at(2).toFloat(exec), args.at(3).toFloat(exec)); else - context->fillText(args.at(exec, 0).toString(exec), args.at(exec, 1).toFloat(exec), args.at(exec, 2).toFloat(exec)); + context->fillText(args.at(0).toString(exec), args.at(1).toFloat(exec), args.at(2).toFloat(exec)); return jsUndefined(); } -JSValuePtr JSCanvasRenderingContext2D::strokeText(ExecState* exec, const ArgList& args) +JSValue JSCanvasRenderingContext2D::strokeText(ExecState* exec, const ArgList& args) { CanvasRenderingContext2D* context = impl(); @@ -380,9 +380,9 @@ JSValuePtr JSCanvasRenderingContext2D::strokeText(ExecState* exec, const ArgList return throwError(exec, SyntaxError); if (args.size() == 4) - context->strokeText(args.at(exec, 0).toString(exec), args.at(exec, 1).toFloat(exec), args.at(exec, 2).toFloat(exec), args.at(exec, 3).toFloat(exec)); + context->strokeText(args.at(0).toString(exec), args.at(1).toFloat(exec), args.at(2).toFloat(exec), args.at(3).toFloat(exec)); else - context->strokeText(args.at(exec, 0).toString(exec), args.at(exec, 1).toFloat(exec), args.at(exec, 2).toFloat(exec)); + context->strokeText(args.at(0).toString(exec), args.at(1).toFloat(exec), args.at(2).toFloat(exec)); return jsUndefined(); } diff --git a/WebCore/bindings/js/JSClipboardCustom.cpp b/WebCore/bindings/js/JSClipboardCustom.cpp index 373ba8a..78dca49 100644 --- a/WebCore/bindings/js/JSClipboardCustom.cpp +++ b/WebCore/bindings/js/JSClipboardCustom.cpp @@ -48,7 +48,7 @@ namespace WebCore { using namespace HTMLNames; -JSValuePtr JSClipboard::types(ExecState* exec) const +JSValue JSClipboard::types(ExecState* exec) const { Clipboard* clipboard = impl(); @@ -56,14 +56,14 @@ JSValuePtr JSClipboard::types(ExecState* exec) const if (types.isEmpty()) return jsNull(); - ArgList list; + MarkedArgumentBuffer list; HashSet<String>::const_iterator end = types.end(); for (HashSet<String>::const_iterator it = types.begin(); it != end; ++it) list.append(jsString(exec, UString(*it))); return constructArray(exec, list); } -JSValuePtr JSClipboard::clearData(ExecState* exec, const ArgList& args) +JSValue JSClipboard::clearData(ExecState* exec, const ArgList& args) { Clipboard* clipboard = impl(); @@ -73,7 +73,7 @@ JSValuePtr JSClipboard::clearData(ExecState* exec, const ArgList& args) } if (args.size() == 1) { - clipboard->clearData(args.at(exec, 0).toString(exec)); + clipboard->clearData(args.at(0).toString(exec)); return jsUndefined(); } @@ -81,7 +81,7 @@ JSValuePtr JSClipboard::clearData(ExecState* exec, const ArgList& args) return throwError(exec, SyntaxError, "clearData: Invalid number of arguments"); } -JSValuePtr JSClipboard::getData(ExecState* exec, const ArgList& args) +JSValue JSClipboard::getData(ExecState* exec, const ArgList& args) { // FIXME: It does not match the rest of the JS bindings to throw on invalid number of arguments. if (args.size() != 1) @@ -90,14 +90,14 @@ JSValuePtr JSClipboard::getData(ExecState* exec, const ArgList& args) Clipboard* clipboard = impl(); bool success; - String result = clipboard->getData(args.at(exec, 0).toString(exec), success); + String result = clipboard->getData(args.at(0).toString(exec), success); if (!success) return jsUndefined(); return jsString(exec, result); } -JSValuePtr JSClipboard::setData(ExecState* exec, const ArgList& args) +JSValue JSClipboard::setData(ExecState* exec, const ArgList& args) { Clipboard* clipboard = impl(); @@ -105,10 +105,10 @@ JSValuePtr JSClipboard::setData(ExecState* exec, const ArgList& args) if (args.size() != 2) return throwError(exec, SyntaxError, "setData: Invalid number of arguments"); - return jsBoolean(clipboard->setData(args.at(exec, 0).toString(exec), args.at(exec, 1).toString(exec))); + return jsBoolean(clipboard->setData(args.at(0).toString(exec), args.at(1).toString(exec))); } -JSValuePtr JSClipboard::setDragImage(ExecState* exec, const ArgList& args) +JSValue JSClipboard::setDragImage(ExecState* exec, const ArgList& args) { Clipboard* clipboard = impl(); @@ -119,11 +119,11 @@ JSValuePtr JSClipboard::setDragImage(ExecState* exec, const ArgList& args) if (args.size() != 3) return throwError(exec, SyntaxError, "setDragImage: Invalid number of arguments"); - int x = args.at(exec, 1).toInt32(exec); - int y = args.at(exec, 2).toInt32(exec); + int x = args.at(1).toInt32(exec); + int y = args.at(2).toInt32(exec); // See if they passed us a node - Node* node = toNode(args.at(exec, 0)); + Node* node = toNode(args.at(0)); if (!node) return throwError(exec, TypeError); diff --git a/WebCore/bindings/js/JSConsoleCustom.cpp b/WebCore/bindings/js/JSConsoleCustom.cpp index ddfe4f7..9c48467 100644 --- a/WebCore/bindings/js/JSConsoleCustom.cpp +++ b/WebCore/bindings/js/JSConsoleCustom.cpp @@ -34,12 +34,14 @@ using namespace JSC; namespace WebCore { +#if ENABLE(JAVASCRIPT_DEBUGGER) + typedef Vector<RefPtr<JSC::Profile> > ProfilesArray; -JSValuePtr JSConsole::profiles(ExecState* exec) const +JSValue JSConsole::profiles(ExecState* exec) const { const ProfilesArray& profiles = impl()->profiles(); - ArgList list; + MarkedArgumentBuffer list; ProfilesArray::const_iterator end = profiles.end(); for (ProfilesArray::const_iterator iter = profiles.begin(); iter != end; ++iter) @@ -48,4 +50,6 @@ JSValuePtr JSConsole::profiles(ExecState* exec) const return constructArray(exec, list); } +#endif + } // namespace WebCore diff --git a/WebCore/bindings/js/JSCoordinatesCustom.cpp b/WebCore/bindings/js/JSCoordinatesCustom.cpp new file mode 100644 index 0000000..720bb9b --- /dev/null +++ b/WebCore/bindings/js/JSCoordinatesCustom.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2009 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 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 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 "JSCoordinates.h" + +#include "Coordinates.h" + +using namespace JSC; + +namespace WebCore { + +JSValue JSCoordinates::altitude(ExecState* exec) const +{ + Coordinates* imp = impl(); + if (!imp->canProvideAltitude()) + return jsNull(); + return jsNumber(exec, imp->altitude()); +} + +JSValue JSCoordinates::altitudeAccuracy(ExecState* exec) const +{ + Coordinates* imp = impl(); + if (!imp->canProvideAltitudeAccuracy()) + return jsNull(); + return jsNumber(exec, imp->altitudeAccuracy()); +} + +JSValue JSCoordinates::heading(ExecState* exec) const +{ + Coordinates* imp = impl(); + if (!imp->canProvideHeading()) + return jsNull(); + return jsNumber(exec, imp->heading()); +} + +JSValue JSCoordinates::speed(ExecState* exec) const +{ + Coordinates* imp = impl(); + if (!imp->canProvideSpeed()) + return jsNull(); + return jsNumber(exec, imp->speed()); +} + +} // namespace WebCore diff --git a/WebCore/bindings/js/JSCustomPositionCallback.cpp b/WebCore/bindings/js/JSCustomPositionCallback.cpp index 6b0bb43..6f9efd9 100644 --- a/WebCore/bindings/js/JSCustomPositionCallback.cpp +++ b/WebCore/bindings/js/JSCustomPositionCallback.cpp @@ -54,7 +54,7 @@ void JSCustomPositionCallback::handleEvent(Geoposition* geoposition, bool& raise JSC::JSLock lock(false); - JSValuePtr function = m_callback->get(exec, Identifier(exec, "handleEvent")); + JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent")); CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) { @@ -68,7 +68,7 @@ void JSCustomPositionCallback::handleEvent(Geoposition* geoposition, bool& raise RefPtr<JSCustomPositionCallback> protect(this); - ArgList args; + MarkedArgumentBuffer args; args.append(toJS(exec, geoposition)); globalObject->globalData()->timeoutChecker.start(); @@ -80,7 +80,7 @@ void JSCustomPositionCallback::handleEvent(Geoposition* geoposition, bool& raise raisedException = true; } - Document::updateDocumentsRendering(); + Document::updateStyleForAllDocuments(); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp b/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp index ecc67dd..cc6cd55 100644 --- a/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp +++ b/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp @@ -54,7 +54,7 @@ void JSCustomPositionErrorCallback::handleEvent(PositionError* positionError) JSC::JSLock lock(false); - JSValuePtr function = m_callback->get(exec, Identifier(exec, "handleEvent")); + JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent")); CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) { @@ -68,7 +68,7 @@ void JSCustomPositionErrorCallback::handleEvent(PositionError* positionError) RefPtr<JSCustomPositionErrorCallback> protect(this); - ArgList args; + MarkedArgumentBuffer args; args.append(toJS(exec, positionError)); globalObject->globalData()->timeoutChecker.start(); @@ -78,7 +78,7 @@ void JSCustomPositionErrorCallback::handleEvent(PositionError* positionError) if (exec->hadException()) reportCurrentException(exec); - Document::updateDocumentsRendering(); + Document::updateStyleForAllDocuments(); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp b/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp index 4b9ff8a..107a491 100644 --- a/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp +++ b/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp @@ -59,7 +59,7 @@ void JSCustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLR JSC::JSLock lock(false); - JSValuePtr function = m_callback->get(exec, Identifier(exec, "handleEvent")); + JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent")); CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) { @@ -73,7 +73,7 @@ void JSCustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLR RefPtr<JSCustomSQLStatementCallback> protect(this); - ArgList args; + MarkedArgumentBuffer args; args.append(toJS(exec, transaction)); args.append(toJS(exec, resultSet)); @@ -87,7 +87,7 @@ void JSCustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLR raisedException = true; } - Document::updateDocumentsRendering(); + Document::updateStyleForAllDocuments(); } } diff --git a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp index 2932919..018dabd 100644 --- a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp +++ b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp @@ -60,7 +60,7 @@ bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, JSC::JSLock lock(false); - JSValuePtr handleEventFunction = m_callback->get(exec, Identifier(exec, "handleEvent")); + JSValue handleEventFunction = m_callback->get(exec, Identifier(exec, "handleEvent")); CallData handleEventCallData; CallType handleEventCallType = handleEventFunction.getCallData(handleEventCallData); CallData callbackCallData; @@ -76,11 +76,11 @@ bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, RefPtr<JSCustomSQLStatementErrorCallback> protect(this); - ArgList args; + MarkedArgumentBuffer args; args.append(toJS(exec, transaction)); args.append(toJS(exec, error)); - JSValuePtr result; + JSValue result; globalObject->globalData()->timeoutChecker.start(); if (handleEventCallType != CallTypeNone) result = call(exec, handleEventFunction, handleEventCallType, handleEventCallData, m_callback, args); @@ -98,7 +98,7 @@ bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, return true; } - Document::updateDocumentsRendering(); + Document::updateStyleForAllDocuments(); return result.toBoolean(exec); } diff --git a/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp b/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp index 9918e71..a41ac78 100644 --- a/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp +++ b/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp @@ -100,7 +100,7 @@ void JSCustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bo JSC::JSLock lock(false); - JSValuePtr handleEventFunction = m_data->callback()->get(exec, Identifier(exec, "handleEvent")); + JSValue handleEventFunction = m_data->callback()->get(exec, Identifier(exec, "handleEvent")); CallData handleEventCallData; CallType handleEventCallType = handleEventFunction.getCallData(handleEventCallData); CallData callbackCallData; @@ -116,7 +116,7 @@ void JSCustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bo RefPtr<JSCustomSQLTransactionCallback> protect(this); - ArgList args; + MarkedArgumentBuffer args; args.append(toJS(exec, transaction)); globalObject->globalData()->timeoutChecker.start(); @@ -132,7 +132,7 @@ void JSCustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bo raisedException = true; } - Document::updateDocumentsRendering(); + Document::updateStyleForAllDocuments(); } } diff --git a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp index f6e59f6..324e2bb 100644 --- a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp +++ b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp @@ -46,49 +46,46 @@ JSCustomSQLTransactionErrorCallback::JSCustomSQLTransactionErrorCallback(JSObjec { } -bool JSCustomSQLTransactionErrorCallback::handleEvent(SQLError* error) +void JSCustomSQLTransactionErrorCallback::handleEvent(SQLError* error) { ASSERT(m_callback); ASSERT(m_frame); - + if (!m_frame->script()->isEnabled()) - return true; - + return; + JSGlobalObject* globalObject = m_frame->script()->globalObject(); ExecState* exec = globalObject->globalExec(); - + JSC::JSLock lock(false); - - JSValuePtr function = m_callback->get(exec, Identifier(exec, "handleEvent")); + + JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent")); CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) { callType = m_callback->getCallData(callData); if (callType == CallTypeNone) { // FIXME: Should an exception be thrown here? - return true; + return; } function = m_callback; } RefPtr<JSCustomSQLTransactionErrorCallback> protect(this); - - ArgList args; + + MarkedArgumentBuffer args; args.append(toJS(exec, error)); - JSValuePtr result; globalObject->globalData()->timeoutChecker.start(); - result = call(exec, function, callType, callData, m_callback, args); + call(exec, function, callType, callData, m_callback, args); globalObject->globalData()->timeoutChecker.stop(); - + if (exec->hadException()) reportCurrentException(exec); - - Document::updateDocumentsRendering(); - - return result.toBoolean(exec); + + Document::updateStyleForAllDocuments(); } - + } #endif // ENABLE(DATABASE) diff --git a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.h b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.h index 5f3d727..be3df29 100644 --- a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.h +++ b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.h @@ -50,7 +50,7 @@ class JSCustomSQLTransactionErrorCallback : public SQLTransactionErrorCallback { public: static PassRefPtr<JSCustomSQLTransactionErrorCallback> create(JSC::JSObject* callback, Frame* frame) { return adoptRef(new JSCustomSQLTransactionErrorCallback(callback, frame)); } - virtual bool handleEvent(SQLError*); + virtual void handleEvent(SQLError*); private: JSCustomSQLTransactionErrorCallback(JSC::JSObject* callback, Frame*); diff --git a/WebCore/bindings/js/JSCustomVoidCallback.cpp b/WebCore/bindings/js/JSCustomVoidCallback.cpp index 23e9fa6..f3f76c4 100644 --- a/WebCore/bindings/js/JSCustomVoidCallback.cpp +++ b/WebCore/bindings/js/JSCustomVoidCallback.cpp @@ -57,7 +57,7 @@ void JSCustomVoidCallback::handleEvent() JSC::JSLock lock(false); - JSValuePtr function = m_callback->get(exec, Identifier(exec, "handleEvent")); + JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent")); CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) { @@ -71,7 +71,7 @@ void JSCustomVoidCallback::handleEvent() RefPtr<JSCustomVoidCallback> protect(this); - ArgList args; + MarkedArgumentBuffer args; globalObject->globalData()->timeoutChecker.start(); call(exec, function, callType, callData, m_callback, args); @@ -80,10 +80,10 @@ void JSCustomVoidCallback::handleEvent() if (exec->hadException()) reportCurrentException(exec); - Document::updateDocumentsRendering(); + Document::updateStyleForAllDocuments(); } -PassRefPtr<VoidCallback> toVoidCallback(ExecState* exec, JSValuePtr value) +PassRefPtr<VoidCallback> toVoidCallback(ExecState* exec, JSValue value) { JSObject* object = value.getObject(); if (!object) diff --git a/WebCore/bindings/js/JSCustomVoidCallback.h b/WebCore/bindings/js/JSCustomVoidCallback.h index f54ddb6..9cd7c34 100644 --- a/WebCore/bindings/js/JSCustomVoidCallback.h +++ b/WebCore/bindings/js/JSCustomVoidCallback.h @@ -55,7 +55,7 @@ namespace WebCore { RefPtr<Frame> m_frame; }; - PassRefPtr<VoidCallback> toVoidCallback(JSC::ExecState*, JSC::JSValuePtr); + PassRefPtr<VoidCallback> toVoidCallback(JSC::ExecState*, JSC::JSValue); } // namespace WebCore diff --git a/WebCore/bindings/js/JSCustomXPathNSResolver.cpp b/WebCore/bindings/js/JSCustomXPathNSResolver.cpp index 5187411..6361e70 100644 --- a/WebCore/bindings/js/JSCustomXPathNSResolver.cpp +++ b/WebCore/bindings/js/JSCustomXPathNSResolver.cpp @@ -39,7 +39,7 @@ namespace WebCore { using namespace JSC; -PassRefPtr<JSCustomXPathNSResolver> JSCustomXPathNSResolver::create(JSC::ExecState* exec, JSC::JSValuePtr value) +PassRefPtr<JSCustomXPathNSResolver> JSCustomXPathNSResolver::create(JSC::ExecState* exec, JSC::JSValue value) { if (value.isUndefinedOrNull()) return 0; @@ -77,7 +77,7 @@ String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix) JSGlobalObject* globalObject = m_frame->script()->globalObject(); ExecState* exec = globalObject->globalExec(); - JSValuePtr function = m_customResolver->get(exec, Identifier(exec, "lookupNamespaceURI")); + JSValue function = m_customResolver->get(exec, Identifier(exec, "lookupNamespaceURI")); CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) { @@ -92,11 +92,11 @@ String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix) RefPtr<JSCustomXPathNSResolver> selfProtector(this); - ArgList args; + MarkedArgumentBuffer args; args.append(jsString(exec, prefix)); globalObject->globalData()->timeoutChecker.start(); - JSValuePtr retval = call(exec, function, callType, callData, m_customResolver, args); + JSValue retval = call(exec, function, callType, callData, m_customResolver, args); globalObject->globalData()->timeoutChecker.stop(); String result; @@ -107,7 +107,7 @@ String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix) result = retval.toString(exec); } - Document::updateDocumentsRendering(); + Document::updateStyleForAllDocuments(); return result; } diff --git a/WebCore/bindings/js/JSCustomXPathNSResolver.h b/WebCore/bindings/js/JSCustomXPathNSResolver.h index fecbb61..44c44f9 100644 --- a/WebCore/bindings/js/JSCustomXPathNSResolver.h +++ b/WebCore/bindings/js/JSCustomXPathNSResolver.h @@ -44,7 +44,7 @@ namespace WebCore { class JSCustomXPathNSResolver : public XPathNSResolver { public: - static PassRefPtr<JSCustomXPathNSResolver> create(JSC::ExecState*, JSC::JSValuePtr); + static PassRefPtr<JSCustomXPathNSResolver> create(JSC::ExecState*, JSC::JSValue); virtual ~JSCustomXPathNSResolver(); diff --git a/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp b/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp index 20d09dd..7e8d9ce 100644 --- a/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp +++ b/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp @@ -60,18 +60,18 @@ void JSDOMApplicationCache::mark() 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) - (*vecIter)->mark(); + (*vecIter)->markJSFunction(); } } -#if ENABLE(APPLICATION_CAHE_DYNAMIC_ENTRIES) +#if ENABLE(APPLICATION_CACHE_DYNAMIC_ENTRIES) -JSValuePtr JSDOMApplicationCache::hasItem(ExecState* exec, const ArgList& args) +JSValue JSDOMApplicationCache::hasItem(ExecState* exec, const ArgList& args) { Frame* frame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); if (!frame) return jsUndefined(); - const KURL& url = frame->loader()->completeURL(args.at(exec, 0).toString(exec)); + const KURL& url = frame->loader()->completeURL(args.at(0).toString(exec)); ExceptionCode ec = 0; bool result = impl()->hasItem(url, ec); @@ -79,12 +79,12 @@ JSValuePtr JSDOMApplicationCache::hasItem(ExecState* exec, const ArgList& args) return jsBoolean(result); } -JSValuePtr JSDOMApplicationCache::add(ExecState* exec, const ArgList& args) +JSValue JSDOMApplicationCache::add(ExecState* exec, const ArgList& args) { Frame* frame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); if (!frame) return jsUndefined(); - const KURL& url = frame->loader()->completeURL(args.at(exec, 0).toString(exec)); + const KURL& url = frame->loader()->completeURL(args.at(0).toString(exec)); ExceptionCode ec = 0; impl()->add(url, ec); @@ -92,12 +92,12 @@ JSValuePtr JSDOMApplicationCache::add(ExecState* exec, const ArgList& args) return jsUndefined(); } -JSValuePtr JSDOMApplicationCache::remove(ExecState* exec, const ArgList& args) +JSValue JSDOMApplicationCache::remove(ExecState* exec, const ArgList& args) { Frame* frame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); if (!frame) return jsUndefined(); - const KURL& url = frame->loader()->completeURL(args.at(exec, 0).toString(exec)); + const KURL& url = frame->loader()->completeURL(args.at(0).toString(exec)); ExceptionCode ec = 0; impl()->remove(url, ec); @@ -105,29 +105,29 @@ JSValuePtr JSDOMApplicationCache::remove(ExecState* exec, const ArgList& args) return jsUndefined(); } -#endif +#endif // ENABLE(APPLICATION_CACHE_DYNAMIC_ENTRIES) -JSValuePtr JSDOMApplicationCache::addEventListener(ExecState* exec, const ArgList& args) +JSValue JSDOMApplicationCache::addEventListener(ExecState* exec, const ArgList& args) { JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1)); + RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(args.at(1)); if (!listener) return jsUndefined(); - impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec)); + impl()->addEventListener(args.at(0).toString(exec), listener.release(), args.at(2).toBoolean(exec)); return jsUndefined(); } -JSValuePtr JSDOMApplicationCache::removeEventListener(ExecState* exec, const ArgList& args) +JSValue JSDOMApplicationCache::removeEventListener(ExecState* exec, const ArgList& args) { JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - JSEventListener* listener = globalObject->findJSEventListener(exec, args.at(exec, 1)); + JSEventListener* listener = globalObject->findJSEventListener(args.at(1)); if (!listener) return jsUndefined(); - impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec)); + impl()->removeEventListener(args.at(0).toString(exec), listener, args.at(2).toBoolean(exec)); return jsUndefined(); } diff --git a/WebCore/bindings/js/JSDOMBinding.cpp b/WebCore/bindings/js/JSDOMBinding.cpp index 6e27dc1..4f58797 100644 --- a/WebCore/bindings/js/JSDOMBinding.cpp +++ b/WebCore/bindings/js/JSDOMBinding.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> * * This library is free software; you can redistribute it and/or @@ -33,6 +33,7 @@ #include "ExceptionCode.h" #include "Frame.h" #include "HTMLImageElement.h" +#include "HTMLScriptElement.h" #include "HTMLNames.h" #include "JSDOMCoreException.h" #include "JSDOMWindowCustom.h" @@ -259,32 +260,47 @@ void forgetAllDOMNodesForDocument(Document* document) removeWrappers(document->wrapperCache()); } +static inline bool isObservableThroughDOM(JSNode* jsNode) +{ + // Certain conditions implicitly make a JS DOM node wrapper observable + // through the DOM, even if no explicit reference to it remains. + + Node* node = jsNode->impl(); + + if (node->inDocument()) { + // 1. If a node is in the document, and its wrapper has custom properties, + // the wrapper is observable because future access to the node through the + // DOM must reflect those properties. + if (jsNode->hasCustomProperties()) + return true; + + // 2. If a node is in the document, and has event listeners, its wrapper is + // observable because its wrapper is responsible for marking those event listeners. + if (node->eventListeners().size()) + return true; // Technically, we may overzealously mark a wrapper for a node that has only non-JS event listeners. Oh well. + } else { + // 3. If a wrapper is the last reference to an image or script element + // that is loading but not in the document, the wrapper is observable + // because it is the only thing keeping the image element alive, and if + // the image element is destroyed, its load event will not fire. + // FIXME: The DOM should manage this issue without the help of JavaScript wrappers. + if (node->hasTagName(imgTag) && !static_cast<HTMLImageElement*>(node)->haveFiredLoadEvent()) + return true; + if (node->hasTagName(scriptTag) && !static_cast<HTMLScriptElement*>(node)->haveFiredLoadEvent()) + return true; + } + + return false; +} + void markDOMNodesForDocument(Document* doc) { - // If a node's JS wrapper holds custom properties, those properties must - // persist every time the node is fetched from the DOM. So, we keep JS - // wrappers like that from being garbage collected. - JSWrapperCache& nodeDict = doc->wrapperCache(); JSWrapperCache::iterator nodeEnd = nodeDict.end(); for (JSWrapperCache::iterator nodeIt = nodeDict.begin(); nodeIt != nodeEnd; ++nodeIt) { JSNode* jsNode = nodeIt->second; - Node* node = jsNode->impl(); - - if (jsNode->marked()) - continue; - - // No need to preserve a wrapper that has no custom properties or is no - // longer fetchable through the DOM. - if (!jsNode->hasCustomProperties() || !node->inDocument()) { - //... unless the wrapper wraps a loading image, since the "new Image" - // syntax allows an orphan image wrapper to be the last reference - // to a loading image, whose load event might have important side-effects. - if (!node->hasTagName(imgTag) || static_cast<HTMLImageElement*>(node)->haveFiredLoadEvent()) - continue; - } - - jsNode->mark(); + if (!jsNode->marked() && isObservableThroughDOM(jsNode)) + jsNode->mark(); } } @@ -340,70 +356,70 @@ void markDOMObjectWrapper(JSGlobalData& globalData, void* object) wrapper->mark(); } -JSValuePtr jsStringOrNull(ExecState* exec, const String& s) +JSValue jsStringOrNull(ExecState* exec, const String& s) { if (s.isNull()) return jsNull(); return jsString(exec, s); } -JSValuePtr jsOwnedStringOrNull(ExecState* exec, const UString& s) +JSValue jsOwnedStringOrNull(ExecState* exec, const UString& s) { if (s.isNull()) return jsNull(); return jsOwnedString(exec, s); } -JSValuePtr jsStringOrUndefined(ExecState* exec, const String& s) +JSValue jsStringOrUndefined(ExecState* exec, const String& s) { if (s.isNull()) return jsUndefined(); return jsString(exec, s); } -JSValuePtr jsStringOrFalse(ExecState* exec, const String& s) +JSValue jsStringOrFalse(ExecState* exec, const String& s) { if (s.isNull()) return jsBoolean(false); return jsString(exec, s); } -JSValuePtr jsStringOrNull(ExecState* exec, const KURL& url) +JSValue jsStringOrNull(ExecState* exec, const KURL& url) { if (url.isNull()) return jsNull(); return jsString(exec, url.string()); } -JSValuePtr jsStringOrUndefined(ExecState* exec, const KURL& url) +JSValue jsStringOrUndefined(ExecState* exec, const KURL& url) { if (url.isNull()) return jsUndefined(); return jsString(exec, url.string()); } -JSValuePtr jsStringOrFalse(ExecState* exec, const KURL& url) +JSValue jsStringOrFalse(ExecState* exec, const KURL& url) { if (url.isNull()) return jsBoolean(false); return jsString(exec, url.string()); } -UString valueToStringWithNullCheck(ExecState* exec, JSValuePtr value) +UString valueToStringWithNullCheck(ExecState* exec, JSValue value) { if (value.isNull()) return UString(); return value.toString(exec); } -UString valueToStringWithUndefinedOrNullCheck(ExecState* exec, JSValuePtr value) +UString valueToStringWithUndefinedOrNullCheck(ExecState* exec, JSValue value) { if (value.isUndefinedOrNull()) return UString(); return value.toString(exec); } -void reportException(JSC::ExecState* exec, JSValuePtr exception) +void reportException(ExecState* exec, JSValue exception) { UString errorMessage = exception.toString(exec); JSObject* exceptionObject = exception.toObject(exec); @@ -412,12 +428,19 @@ void reportException(JSC::ExecState* exec, JSValuePtr exception) exec->clearException(); ScriptExecutionContext* scriptExecutionContext = static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->scriptExecutionContext(); + ASSERT(scriptExecutionContext); + + // Crash data indicates null-dereference crashes at this point in the Safari 4 Public Beta. + // It's harmless to return here without reporting the exception to the log and the debugger in this case. + if (!scriptExecutionContext) + return; + scriptExecutionContext->reportException(errorMessage, lineNumber, exceptionSourceURL); } -void reportCurrentException(JSC::ExecState* exec) +void reportCurrentException(ExecState* exec) { - JSValuePtr exception = exec->exception(); + JSValue exception = exec->exception(); exec->clearException(); reportException(exec, exception); } @@ -430,7 +453,7 @@ void setDOMException(ExecState* exec, ExceptionCode ec) ExceptionCodeDescription description; getExceptionCodeDescription(ec, description); - JSValuePtr errorObject = noValue(); + JSValue errorObject; switch (description.type) { case DOMExceptionType: errorObject = toJS(exec, DOMCoreException::create(description)); @@ -481,6 +504,12 @@ bool allowsAccessFromFrame(ExecState* exec, Frame* frame, String& message) return window && window->allowsAccessFrom(exec, message); } +bool shouldAllowNavigation(ExecState* exec, Frame* frame) +{ + Frame* lexicalFrame = toLexicalFrame(exec); + return lexicalFrame && lexicalFrame->loader()->shouldAllowNavigation(frame); +} + void printErrorMessageForFrame(Frame* frame, const String& message) { if (!frame) @@ -489,39 +518,59 @@ void printErrorMessageForFrame(Frame* frame, const String& message) window->printErrorMessage(message); } -JSValuePtr objectToStringFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) +Frame* toLexicalFrame(ExecState* exec) { - return new (exec) PrototypeFunction(exec, 0, propertyName, objectProtoFuncToString); + return asJSDOMWindow(exec->lexicalGlobalObject())->impl()->frame(); } -ScriptState* scriptStateFromNode(Node* node) +Frame* toDynamicFrame(ExecState* exec) { - if (!node) - return 0; - Document* document = node->document(); - if (!document) - return 0; - Frame* frame = document->frame(); + return asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); +} + +bool processingUserGesture(ExecState* exec) +{ + Frame* frame = toDynamicFrame(exec); + return frame && frame->script()->processingUserGesture(); +} + +KURL completeURL(ExecState* exec, const String& relativeURL) +{ + // For histoical reasons, we need to complete the URL using the dynamic frame. + Frame* frame = toDynamicFrame(exec); if (!frame) - return 0; - if (!frame->script()->isEnabled()) - return 0; - return frame->script()->globalObject()->globalExec(); + return KURL(); + return frame->loader()->completeURL(relativeURL); } -Structure* getCachedDOMStructure(ExecState* exec, const ClassInfo* classInfo) +JSValue objectToStringFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) { - JSDOMStructureMap& structures = static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->structures(); + return new (exec) PrototypeFunction(exec, 0, propertyName, objectProtoFuncToString); +} + +Structure* getCachedDOMStructure(JSDOMGlobalObject* globalObject, const ClassInfo* classInfo) +{ + JSDOMStructureMap& structures = globalObject->structures(); return structures.get(classInfo).get(); } -Structure* cacheDOMStructure(ExecState* exec, PassRefPtr<Structure> structure, const ClassInfo* classInfo) +Structure* cacheDOMStructure(JSDOMGlobalObject* globalObject, PassRefPtr<Structure> structure, const ClassInfo* classInfo) { - JSDOMStructureMap& structures = static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->structures(); + JSDOMStructureMap& structures = globalObject->structures(); ASSERT(!structures.contains(classInfo)); return structures.set(classInfo, structure).first->second.get(); } +Structure* getCachedDOMStructure(ExecState* exec, const ClassInfo* classInfo) +{ + return getCachedDOMStructure(static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()), classInfo); +} + +Structure* cacheDOMStructure(ExecState* exec, PassRefPtr<Structure> structure, const ClassInfo* classInfo) +{ + return cacheDOMStructure(static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()), structure, classInfo); +} + JSObject* getCachedDOMConstructor(ExecState* exec, const ClassInfo* classInfo) { JSDOMConstructorMap& constructors = static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->constructors(); diff --git a/WebCore/bindings/js/JSDOMBinding.h b/WebCore/bindings/js/JSDOMBinding.h index 71da21b..1378c91 100644 --- a/WebCore/bindings/js/JSDOMBinding.h +++ b/WebCore/bindings/js/JSDOMBinding.h @@ -25,7 +25,6 @@ #include <runtime/Completion.h> #include <runtime/Lookup.h> #include <runtime/JSFunction.h> -#include "ScriptState.h" #include <wtf/Noncopyable.h> namespace JSC { @@ -73,21 +72,27 @@ namespace WebCore { void markActiveObjectsForContext(JSC::JSGlobalData&, ScriptExecutionContext*); void markDOMObjectWrapper(JSC::JSGlobalData& globalData, void* object); + JSC::Structure* getCachedDOMStructure(JSDOMGlobalObject*, const JSC::ClassInfo*); + JSC::Structure* cacheDOMStructure(JSDOMGlobalObject*, PassRefPtr<JSC::Structure>, const JSC::ClassInfo*); JSC::Structure* getCachedDOMStructure(JSC::ExecState*, const JSC::ClassInfo*); JSC::Structure* cacheDOMStructure(JSC::ExecState*, PassRefPtr<JSC::Structure>, const JSC::ClassInfo*); JSC::JSObject* getCachedDOMConstructor(JSC::ExecState*, const JSC::ClassInfo*); void cacheDOMConstructor(JSC::ExecState*, const JSC::ClassInfo*, JSC::JSObject* constructor); - template<class WrapperClass> inline JSC::Structure* getDOMStructure(JSC::ExecState* exec) + template<class WrapperClass> inline JSC::Structure* getDOMStructure(JSC::ExecState* exec, JSDOMGlobalObject* globalObject) { - if (JSC::Structure* structure = getCachedDOMStructure(exec, &WrapperClass::s_info)) + if (JSC::Structure* structure = getCachedDOMStructure(globalObject, &WrapperClass::s_info)) return structure; - return cacheDOMStructure(exec, WrapperClass::createStructure(WrapperClass::createPrototype(exec)), &WrapperClass::s_info); + return cacheDOMStructure(globalObject, WrapperClass::createStructure(WrapperClass::createPrototype(exec, globalObject)), &WrapperClass::s_info); + } + template<class WrapperClass> inline JSC::Structure* getDOMStructure(JSC::ExecState* exec) + { + return getDOMStructure<WrapperClass>(exec, static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())); } - template<class WrapperClass> inline JSC::JSObject* getDOMPrototype(JSC::ExecState* exec) + template<class WrapperClass> inline JSC::JSObject* getDOMPrototype(JSC::ExecState* exec, JSC::JSGlobalObject* globalObject) { - return static_cast<JSC::JSObject*>(asObject(getDOMStructure<WrapperClass>(exec)->storedPrototype())); + return static_cast<JSC::JSObject*>(asObject(getDOMStructure<WrapperClass>(exec, static_cast<JSDOMGlobalObject*>(globalObject))->storedPrototype())); } #define CREATE_DOM_OBJECT_WRAPPER(exec, className, object) createDOMObjectWrapper<JS##className>(exec, static_cast<className*>(object)) template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object) @@ -98,7 +103,7 @@ namespace WebCore { cacheDOMObjectWrapper(exec->globalData(), object, wrapper); return wrapper; } - template<class WrapperClass, class DOMClass> inline JSC::JSValuePtr getDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object) + template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object) { if (!object) return JSC::jsNull(); @@ -117,7 +122,7 @@ namespace WebCore { cacheDOMObjectWrapper(exec->globalData(), object, wrapper); return wrapper; } - template<class WrapperClass, class DOMClass> inline JSC::JSValuePtr getDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object, SVGElement* context) + template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object, SVGElement* context) { if (!object) return JSC::jsNull(); @@ -136,7 +141,7 @@ namespace WebCore { cacheDOMNodeWrapper(node->document(), node, wrapper); return wrapper; } - template<class WrapperClass, class DOMClass> inline JSC::JSValuePtr getDOMNodeWrapper(JSC::ExecState* exec, DOMClass* node) + template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMNodeWrapper(JSC::ExecState* exec, DOMClass* node) { if (!node) return JSC::jsNull(); @@ -147,29 +152,29 @@ namespace WebCore { const JSC::HashTable* getHashTableForGlobalData(JSC::JSGlobalData&, const JSC::HashTable* staticTable); - void reportException(JSC::ExecState*, JSC::JSValuePtr exception); + void reportException(JSC::ExecState*, JSC::JSValue exception); void reportCurrentException(JSC::ExecState*); // Convert a DOM implementation exception code into a JavaScript exception in the execution state. void setDOMException(JSC::ExecState*, ExceptionCode); - JSC::JSValuePtr jsStringOrNull(JSC::ExecState*, const String&); // null if the string is null - JSC::JSValuePtr jsStringOrNull(JSC::ExecState*, const KURL&); // null if the URL is null + JSC::JSValue jsStringOrNull(JSC::ExecState*, const String&); // null if the string is null + JSC::JSValue jsStringOrNull(JSC::ExecState*, const KURL&); // null if the URL is null - JSC::JSValuePtr jsStringOrUndefined(JSC::ExecState*, const String&); // undefined if the string is null - JSC::JSValuePtr jsStringOrUndefined(JSC::ExecState*, const KURL&); // undefined if the URL is null + JSC::JSValue jsStringOrUndefined(JSC::ExecState*, const String&); // undefined if the string is null + JSC::JSValue jsStringOrUndefined(JSC::ExecState*, const KURL&); // undefined if the URL is null - JSC::JSValuePtr jsStringOrFalse(JSC::ExecState*, const String&); // boolean false if the string is null - JSC::JSValuePtr jsStringOrFalse(JSC::ExecState*, const KURL&); // boolean false if the URL is null + JSC::JSValue jsStringOrFalse(JSC::ExecState*, const String&); // boolean false if the string is null + JSC::JSValue jsStringOrFalse(JSC::ExecState*, 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. - JSC::JSValuePtr jsOwnedStringOrNull(JSC::ExecState*, const JSC::UString&); + JSC::JSValue jsOwnedStringOrNull(JSC::ExecState*, const JSC::UString&); - JSC::UString valueToStringWithNullCheck(JSC::ExecState*, JSC::JSValuePtr); // null if the value is null - JSC::UString valueToStringWithUndefinedOrNullCheck(JSC::ExecState*, JSC::JSValuePtr); // null if the value is null or undefined + JSC::UString valueToStringWithNullCheck(JSC::ExecState*, JSC::JSValue); // null if the value is null + JSC::UString valueToStringWithUndefinedOrNullCheck(JSC::ExecState*, JSC::JSValue); // null if the value is null or undefined - template <typename T> inline JSC::JSValuePtr toJS(JSC::ExecState* exec, PassRefPtr<T> ptr) { return toJS(exec, ptr.get()); } + template <typename T> inline JSC::JSValue toJS(JSC::ExecState* exec, PassRefPtr<T> ptr) { return toJS(exec, ptr.get()); } bool checkNodeSecurity(JSC::ExecState*, Node*); @@ -178,10 +183,14 @@ namespace WebCore { // because we do not want current property values involved at all. bool allowsAccessFromFrame(JSC::ExecState*, Frame*); bool allowsAccessFromFrame(JSC::ExecState*, Frame*, String& message); + bool shouldAllowNavigation(JSC::ExecState*, Frame*); void printErrorMessageForFrame(Frame*, const String& message); - JSC::JSValuePtr objectToStringFunctionGetter(JSC::ExecState*, const JSC::Identifier& propertyName, const JSC::PropertySlot&); + JSC::JSValue objectToStringFunctionGetter(JSC::ExecState*, const JSC::Identifier& propertyName, const JSC::PropertySlot&); - ScriptState* scriptStateFromNode(Node*); + Frame* toLexicalFrame(JSC::ExecState*); + Frame* toDynamicFrame(JSC::ExecState*); + bool processingUserGesture(JSC::ExecState*); + KURL completeURL(JSC::ExecState*, const String& relativeURL); } // namespace WebCore diff --git a/WebCore/bindings/js/JSDOMGlobalObject.cpp b/WebCore/bindings/js/JSDOMGlobalObject.cpp index 849c470..a7f7b21 100644 --- a/WebCore/bindings/js/JSDOMGlobalObject.cpp +++ b/WebCore/bindings/js/JSDOMGlobalObject.cpp @@ -30,12 +30,11 @@ #include "Document.h" #include "JSDOMWindow.h" #include "JSEventListener.h" -#ifdef ANDROID_FIX // these are generated files, need to check ENABLE(WORKERS) + #if ENABLE(WORKERS) #include "JSWorkerContext.h" -#endif -#endif #include "WorkerContext.h" +#endif using namespace JSC; @@ -53,26 +52,10 @@ JSDOMGlobalObject::JSDOMGlobalObject(PassRefPtr<Structure> structure, JSDOMGloba JSDOMGlobalObject::~JSDOMGlobalObject() { - // Clear any backpointers to the window - ProtectedListenersMap::iterator i1 = d()->jsProtectedEventListeners.begin(); - ProtectedListenersMap::iterator e1 = d()->jsProtectedEventListeners.end(); - for (; i1 != e1; ++i1) - i1->second->clearGlobalObject(); - - i1 = d()->jsProtectedInlineEventListeners.begin(); - e1 = d()->jsProtectedInlineEventListeners.end(); - for (; i1 != e1; ++i1) - i1->second->clearGlobalObject(); - - JSListenersMap::iterator i2 = d()->jsEventListeners.begin(); - JSListenersMap::iterator e2 = d()->jsEventListeners.end(); - for (; i2 != e2; ++i2) - i2->second->clearGlobalObject(); - - i2 = d()->jsInlineEventListeners.begin(); - e2 = d()->jsInlineEventListeners.end(); - for (; i2 != e2; ++i2) - i2->second->clearGlobalObject(); + JSListenersMap::iterator it = d()->jsEventListeners.begin(); + JSListenersMap::iterator end = d()->jsEventListeners.end(); + for (; it != end; ++it) + it->second->clearGlobalObject(); } void JSDOMGlobalObject::mark() @@ -90,56 +73,32 @@ void JSDOMGlobalObject::mark() } } -JSProtectedEventListener* JSDOMGlobalObject::findJSProtectedEventListener(JSValuePtr val, bool isInline) -{ - if (!val.isObject()) - return 0; - JSObject* object = asObject(val); - ProtectedListenersMap& listeners = isInline ? d()->jsProtectedInlineEventListeners : d()->jsProtectedEventListeners; - return listeners.get(object); -} - -PassRefPtr<JSProtectedEventListener> JSDOMGlobalObject::findOrCreateJSProtectedEventListener(ExecState*, JSValuePtr val, bool isInline) -{ - if (JSProtectedEventListener* listener = findJSProtectedEventListener(val, isInline)) - return listener; - - if (!val.isObject()) - return 0; - - // The JSProtectedEventListener constructor adds it to our jsProtectedEventListeners map. - return JSProtectedEventListener::create(asObject(val), this, isInline).get(); -} - -JSEventListener* JSDOMGlobalObject::findJSEventListener(ExecState*, JSValuePtr val, bool isInline) +JSEventListener* JSDOMGlobalObject::findJSEventListener(JSValue val) { if (!val.isObject()) return 0; - JSListenersMap& listeners = isInline ? d()->jsInlineEventListeners : d()->jsEventListeners; - return listeners.get(asObject(val)); + return d()->jsEventListeners.get(asObject(val)); } -PassRefPtr<JSEventListener> JSDOMGlobalObject::findOrCreateJSEventListener(ExecState* exec, JSValuePtr val, bool isInline) +PassRefPtr<JSEventListener> JSDOMGlobalObject::findOrCreateJSEventListener(JSValue val) { - if (JSEventListener* listener = findJSEventListener(exec, val, isInline)) + if (JSEventListener* listener = findJSEventListener(val)) return listener; if (!val.isObject()) return 0; // The JSEventListener constructor adds it to our jsEventListeners map. - return JSEventListener::create(asObject(val), this, isInline).get(); + return JSEventListener::create(asObject(val), this, false).get(); } -JSDOMGlobalObject::ProtectedListenersMap& JSDOMGlobalObject::jsProtectedEventListeners() +PassRefPtr<JSEventListener> JSDOMGlobalObject::createJSAttributeEventListener(JSValue val) { - return d()->jsProtectedEventListeners; -} + if (!val.isObject()) + return 0; -JSDOMGlobalObject::ProtectedListenersMap& JSDOMGlobalObject::jsProtectedInlineEventListeners() -{ - return d()->jsProtectedInlineEventListeners; + return JSEventListener::create(asObject(val), this, true).get(); } JSDOMGlobalObject::JSListenersMap& JSDOMGlobalObject::jsEventListeners() @@ -147,17 +106,12 @@ JSDOMGlobalObject::JSListenersMap& JSDOMGlobalObject::jsEventListeners() return d()->jsEventListeners; } -JSDOMGlobalObject::JSListenersMap& JSDOMGlobalObject::jsInlineEventListeners() -{ - return d()->jsInlineEventListeners; -} - void JSDOMGlobalObject::setCurrentEvent(Event* evt) { d()->evt = evt; } -Event* JSDOMGlobalObject::currentEvent() +Event* JSDOMGlobalObject::currentEvent() const { return d()->evt; } diff --git a/WebCore/bindings/js/JSDOMGlobalObject.h b/WebCore/bindings/js/JSDOMGlobalObject.h index 6ca3797..8e4e820 100644 --- a/WebCore/bindings/js/JSDOMGlobalObject.h +++ b/WebCore/bindings/js/JSDOMGlobalObject.h @@ -32,7 +32,7 @@ namespace WebCore { class Event; - class JSProtectedEventListener; + class JSLazyEventListener; class JSEventListener; class ScriptExecutionContext; @@ -53,28 +53,22 @@ namespace WebCore { virtual ScriptExecutionContext* scriptExecutionContext() const = 0; - // Finds a wrapper of a JS EventListener, returns 0 if no existing one. - JSProtectedEventListener* findJSProtectedEventListener(JSC::JSValuePtr, bool isInline = false); - - // Finds or creates a wrapper of a JS EventListener. JS EventListener object is GC-protected. - PassRefPtr<JSProtectedEventListener> findOrCreateJSProtectedEventListener(JSC::ExecState*, JSC::JSValuePtr, bool isInline = false); - // Finds a wrapper of a GC-unprotected JS EventListener, returns 0 if no existing one. - JSEventListener* findJSEventListener(JSC::ExecState*, JSC::JSValuePtr, bool isInline = false); + JSEventListener* findJSEventListener(JSC::JSValue); // Finds or creates a wrapper of a JS EventListener. JS EventListener object is *NOT* GC-protected. - PassRefPtr<JSEventListener> findOrCreateJSEventListener(JSC::ExecState*, JSC::JSValuePtr, bool isInline = false); + PassRefPtr<JSEventListener> findOrCreateJSEventListener(JSC::JSValue); + + // Creates a GC-protected JS EventListener for an "onXXX" event attribute. + // These listeners cannot be removed through the removeEventListener API. + PassRefPtr<JSEventListener> createJSAttributeEventListener(JSC::JSValue); - typedef HashMap<JSC::JSObject*, JSProtectedEventListener*> ProtectedListenersMap; typedef HashMap<JSC::JSObject*, JSEventListener*> JSListenersMap; - ProtectedListenersMap& jsProtectedEventListeners(); - ProtectedListenersMap& jsProtectedInlineEventListeners(); JSListenersMap& jsEventListeners(); - JSListenersMap& jsInlineEventListeners(); void setCurrentEvent(Event*); - Event* currentEvent(); + Event* currentEvent() const; virtual void mark(); @@ -85,10 +79,7 @@ namespace WebCore { JSDOMStructureMap structures; JSDOMConstructorMap constructors; - JSDOMGlobalObject::ProtectedListenersMap jsProtectedEventListeners; - JSDOMGlobalObject::ProtectedListenersMap jsProtectedInlineEventListeners; JSDOMGlobalObject::JSListenersMap jsEventListeners; - JSDOMGlobalObject::JSListenersMap jsInlineEventListeners; Event* evt; }; @@ -108,11 +99,11 @@ namespace WebCore { } template<class ConstructorClass> - inline JSC::JSObject* getDOMConstructor(JSC::ExecState* exec, JSDOMGlobalObject* globalObject) + inline JSC::JSObject* getDOMConstructor(JSC::ExecState* exec, const JSDOMGlobalObject* globalObject) { if (JSC::JSObject* constructor = globalObject->constructors().get(&ConstructorClass::s_info)) return constructor; - JSC::JSObject* constructor = new (exec) ConstructorClass(exec, globalObject->scriptExecutionContext()); + JSC::JSObject* constructor = new (exec) ConstructorClass(exec, const_cast<JSDOMGlobalObject*>(globalObject)); ASSERT(!globalObject->constructors().contains(&ConstructorClass::s_info)); globalObject->constructors().set(&ConstructorClass::s_info, constructor); return constructor; diff --git a/WebCore/bindings/js/JSDOMStringListCustom.cpp b/WebCore/bindings/js/JSDOMStringListCustom.cpp index d1ea663..ac088af 100644 --- a/WebCore/bindings/js/JSDOMStringListCustom.cpp +++ b/WebCore/bindings/js/JSDOMStringListCustom.cpp @@ -32,14 +32,14 @@ using namespace JSC; namespace WebCore { -JSValuePtr JSDOMStringList::getByIndex(ExecState* exec, unsigned index) +JSValue JSDOMStringList::getByIndex(ExecState* exec, unsigned index) { return jsString(exec, impl()->item(index)); } -JSValuePtr JSDOMStringList::item(ExecState* exec, const ArgList& args) +JSValue JSDOMStringList::item(ExecState* exec, const ArgList& args) { - unsigned index = args.at(exec, 0).toUInt32(exec); + unsigned index = args.at(0).toUInt32(exec); if (index >= impl()->length()) return jsNull(); diff --git a/WebCore/bindings/js/JSDOMWindowBase.cpp b/WebCore/bindings/js/JSDOMWindowBase.cpp index 5e5ac2f..4fd1139 100644 --- a/WebCore/bindings/js/JSDOMWindowBase.cpp +++ b/WebCore/bindings/js/JSDOMWindowBase.cpp @@ -1,7 +1,7 @@ /* * 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) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reseved. * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) * * This library is free software; you can redistribute it and/or @@ -25,106 +25,29 @@ #include "CString.h" #include "Console.h" -#include "DOMTimer.h" #include "DOMWindow.h" #include "Element.h" -#include "FloatRect.h" #include "Frame.h" -#include "FrameLoadRequest.h" +#include "HTMLCollection.h" #include "HTMLDocument.h" #include "InspectorController.h" -#include "JSAudioConstructor.h" #include "JSDOMWindowCustom.h" -#include "JSEvent.h" #include "JSHTMLCollection.h" -#include "JSImageConstructor.h" -#include "JSMessageChannelConstructor.h" #include "JSNode.h" -#include "JSWebKitCSSMatrixConstructor.h" -#include "JSOptionConstructor.h" -#include "JSWebKitPointConstructor.h" -#include "JSWorkerConstructor.h" -#include "JSXMLHttpRequestConstructor.h" -#include "JSXSLTProcessorConstructor.h" #include "Logging.h" -#include "MediaPlayer.h" #include "Page.h" -#include "PlatformScreen.h" -#include "PluginInfoStore.h" -#include "RenderView.h" -#include "ScheduledAction.h" #include "ScriptController.h" #include "SecurityOrigin.h" #include "Settings.h" -#include "WindowFeatures.h" -#include <runtime/JSLock.h> -#include <wtf/MathExtras.h> using namespace JSC; -static JSValuePtr windowProtoFuncOpen(ExecState*, JSObject*, JSValuePtr, const ArgList&); -static JSValuePtr windowProtoFuncShowModalDialog(ExecState*, JSObject*, JSValuePtr, const ArgList&); -static JSValuePtr windowProtoFuncNotImplemented(ExecState*, JSObject*, JSValuePtr, const ArgList&); - -static JSValuePtr jsDOMWindowBaseCrypto(ExecState*, const Identifier&, const PropertySlot&); -static JSValuePtr jsDOMWindowBaseEvent(ExecState*, const Identifier&, const PropertySlot&); -static void setJSDOMWindowBaseEvent(ExecState*, JSObject*, JSValuePtr); - -// Constructors -static JSValuePtr jsDOMWindowBaseAudio(ExecState*, const Identifier&, const PropertySlot&); -static void setJSDOMWindowBaseAudio(ExecState*, JSObject*, JSValuePtr); -static JSValuePtr jsDOMWindowBaseImage(ExecState*, const Identifier&, const PropertySlot&); -static void setJSDOMWindowBaseImage(ExecState*, JSObject*, JSValuePtr); -static JSValuePtr jsDOMWindowBaseMessageChannel(ExecState*, const Identifier&, const PropertySlot&); -static void setJSDOMWindowBaseMessageChannel(ExecState*, JSObject*, JSValuePtr); -static JSValuePtr jsDOMWindowBaseWorker(ExecState*, const Identifier&, const PropertySlot&); -static void setJSDOMWindowBaseWorker(ExecState*, JSObject*, JSValuePtr); -static JSValuePtr jsDOMWindowBaseOption(ExecState*, const Identifier&, const PropertySlot&); -static void setJSDOMWindowBaseOption(ExecState*, JSObject*, JSValuePtr); -static JSValuePtr jsDOMWindowBaseWebKitCSSMatrix(ExecState*, const Identifier&, const PropertySlot&); -static void setJSDOMWindowBaseWebKitCSSMatrix(ExecState*, JSObject*, JSValuePtr); -static JSValuePtr jsDOMWindowBaseWebKitPoint(ExecState*, const Identifier&, const PropertySlot&); -static void setJSDOMWindowBaseWebKitPoint(ExecState*, JSObject*, JSValuePtr); -static JSValuePtr jsDOMWindowBaseXMLHttpRequest(ExecState*, const Identifier&, const PropertySlot&); -static void setJSDOMWindowBaseXMLHttpRequest(ExecState*, JSObject*, JSValuePtr); -static JSValuePtr jsDOMWindowBaseXSLTProcessor(ExecState*, const Identifier&, const PropertySlot&); -static void setJSDOMWindowBaseXSLTProcessor(ExecState*, JSObject*, JSValuePtr); - -#include "JSDOMWindowBase.lut.h" - namespace WebCore { -////////////////////// JSDOMWindowBase Object //////////////////////// - -const ClassInfo JSDOMWindowBase::s_info = { "Window", 0, &JSDOMWindowBaseTable, 0 }; - -/* -@begin JSDOMWindowBaseTable -# -- Functions -- - open windowProtoFuncOpen DontDelete|Function 3 - showModalDialog windowProtoFuncShowModalDialog DontDelete|Function 1 -# Not implemented - captureEvents windowProtoFuncNotImplemented DontDelete|Function 0 - releaseEvents windowProtoFuncNotImplemented DontDelete|Function 0 -# -- Attributes -- - crypto jsDOMWindowBaseCrypto DontDelete|ReadOnly - event jsDOMWindowBaseEvent DontDelete -# -- Constructors -- - Audio jsDOMWindowBaseAudio DontDelete - Image jsDOMWindowBaseImage DontDelete - MessageChannel jsDOMWindowBaseMessageChannel DontDelete - Option jsDOMWindowBaseOption DontDelete - WebKitCSSMatrix jsDOMWindowBaseWebKitCSSMatrix DontDelete - WebKitPoint jsDOMWindowBaseWebKitPoint DontDelete - Worker jsDOMWindowBaseWorker DontDelete - XMLHttpRequest jsDOMWindowBaseXMLHttpRequest DontDelete - XSLTProcessor jsDOMWindowBaseXSLTProcessor DontDelete -@end -*/ +const ClassInfo JSDOMWindowBase::s_info = { "Window", 0, 0, 0 }; JSDOMWindowBase::JSDOMWindowBaseData::JSDOMWindowBaseData(PassRefPtr<DOMWindow> window, JSDOMWindowShell* shell) : impl(window) - , returnValueSlot(0) , shell(shell) { } @@ -147,411 +70,22 @@ void JSDOMWindowBase::updateDocument() symbolTablePutWithAttributes(Identifier(exec, "document"), toJS(exec, d()->impl->document()), DontDelete | ReadOnly); } -JSDOMWindowBase::~JSDOMWindowBase() -{ - if (d()->impl->frame()) - d()->impl->frame()->script()->clearFormerWindow(asJSDOMWindow(this)); -} - ScriptExecutionContext* JSDOMWindowBase::scriptExecutionContext() const { return d()->impl->document(); } -static bool allowPopUp(ExecState* exec) -{ - Frame* frame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); - - ASSERT(frame); - if (frame->script()->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, JSValuePtr dialogArgs) -{ - Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); - ASSERT(activeFrame); - - ResourceRequest request; - - request.setHTTPReferrer(activeFrame->loader()->outgoingReferrer()); - FrameLoader::addHTTPOriginIfNeeded(request, activeFrame->loader()->outgoingOrigin()); - FrameLoadRequest frameRequest(request, frameName); - - // 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; - // We pass in the opener frame here so it can be used for looking up the frame name, in case the active frame - // is different from the opener frame, and the name references a frame relative to the opener frame, for example - // "_self" or "_parent". - Frame* newFrame = activeFrame->loader()->createWindow(openerFrame->loader(), frameRequest, windowFeatures, created); - if (!newFrame) - return 0; - - newFrame->loader()->setOpener(openerFrame); - newFrame->loader()->setOpenedByDOM(); - - JSDOMWindow* newWindow = toJSDOMWindow(newFrame); - - if (dialogArgs) - newWindow->putDirect(Identifier(exec, "dialogArguments"), dialogArgs); - - if (!protocolIs(url, "javascript") || newWindow->allowsAccessFrom(exec)) { - KURL completedURL = url.isEmpty() ? KURL("") : activeFrame->document()->completeURL(url); - bool userGesture = activeFrame->script()->processingUserGesture(); - - if (created) - newFrame->loader()->changeLocation(completedURL, activeFrame->loader()->outgoingReferrer(), false, false, userGesture); - else if (!url.isEmpty()) - newFrame->loader()->scheduleLocationChange(completedURL.string(), activeFrame->loader()->outgoingReferrer(), !activeFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture); - } - - return newFrame; -} - -static bool canShowModalDialog(const Frame* frame) -{ - if (!frame) - return false; - - Page* page = frame->page(); - if (!page) - return false; - - return page->chrome()->canRunModal(); -} - -static bool canShowModalDialogNow(const Frame* frame) -{ - if (!frame) - return false; - - Page* page = frame->page(); - if (!page) - return false; - - return page->chrome()->canRunModalNow(); -} - -static JSValuePtr showModalDialog(ExecState* exec, Frame* frame, const String& url, JSValuePtr 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(); - - JSDOMWindow* dialogWindow = toJSDOMWindow(dialogFrame); - - // Get the return value either just before clearing the dialog window's - // properties (in JSDOMWindowBase::clear), or when on return from runModal. - JSValuePtr returnValue = noValue(); - dialogWindow->setReturnValueSlot(&returnValue); - dialogFrame->page()->chrome()->runModal(); - dialogWindow->setReturnValueSlot(0); - - // If we don't have a return value, get it now. - // Either JSDOMWindowBase::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(Identifier(exec, "returnValue")); - - return returnValue ? returnValue : jsUndefined(); -} - -} // namespace WebCore - -using namespace WebCore; - -JSValuePtr jsDOMWindowBaseCrypto(ExecState*, const Identifier&, const PropertySlot&) -{ - return jsUndefined(); // FIXME: implement this -} - -JSValuePtr jsDOMWindowBaseEvent(ExecState* exec, const Identifier&, const PropertySlot& slot) -{ - if (!static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->allowsAccessFrom(exec)) - return jsUndefined(); - if (!static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->currentEvent()) - return jsUndefined(); - return toJS(exec, static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->currentEvent()); -} - -JSValuePtr jsDOMWindowBaseImage(ExecState* exec, const Identifier&, const PropertySlot& slot) -{ - if (!static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->allowsAccessFrom(exec)) - return jsUndefined(); - return getDOMConstructor<JSImageConstructor>(exec, static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))); -} - -#if !ENABLE(CHANNEL_MESSAGING) - -JSValuePtr jsDOMWindowBaseMessageChannel(ExecState*, const Identifier&, const PropertySlot&) -{ - return jsUndefined(); -} - -#else - -JSValuePtr jsDOMWindowBaseMessageChannel(ExecState* exec, const Identifier&, const PropertySlot& slot) -{ - if (!static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->allowsAccessFrom(exec)) - return jsUndefined(); - return getDOMConstructor<JSMessageChannelConstructor>(exec, static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))); -} - -#endif - -JSValuePtr jsDOMWindowBaseOption(ExecState* exec, const Identifier&, const PropertySlot& slot) -{ - if (!static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->allowsAccessFrom(exec)) - return jsUndefined(); - return getDOMConstructor<JSOptionConstructor>(exec, static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))); -} - -JSValuePtr jsDOMWindowBaseWebKitCSSMatrix(ExecState* exec, const Identifier&, const PropertySlot& slot) -{ - if (!static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->allowsAccessFrom(exec)) - return jsUndefined(); - return getDOMConstructor<JSWebKitCSSMatrixConstructor>(exec); -} - -JSValuePtr jsDOMWindowBaseXMLHttpRequest(ExecState* exec, const Identifier&, const PropertySlot& slot) -{ - if (!static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->allowsAccessFrom(exec)) - return jsUndefined(); - return getDOMConstructor<JSXMLHttpRequestConstructor>(exec, static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))); -} - -JSValuePtr jsDOMWindowBaseAudio(ExecState* exec, const Identifier&, const PropertySlot& slot) -{ -#if ENABLE(VIDEO) - if (!static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->allowsAccessFrom(exec)) - return jsUndefined(); - if (!MediaPlayer::isAvailable()) - return jsUndefined(); - return getDOMConstructor<JSAudioConstructor>(exec, static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))); -#else - UNUSED_PARAM(exec); - UNUSED_PARAM(slot); - return jsUndefined(); -#endif -} - -JSValuePtr jsDOMWindowBaseWebKitPoint(ExecState* exec, const Identifier&, const PropertySlot& slot) -{ - if (!static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->allowsAccessFrom(exec)) - return jsUndefined(); - return getDOMConstructor<JSWebKitPointConstructor>(exec); -} - -JSValuePtr jsDOMWindowBaseWorker(ExecState* exec, const Identifier&, const PropertySlot& slot) -{ -#if ENABLE(WORKERS) - if (!static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->allowsAccessFrom(exec)) - return jsUndefined(); - return getDOMConstructor<JSWorkerConstructor>(exec); -#else - UNUSED_PARAM(exec); - UNUSED_PARAM(slot); - return jsUndefined(); -#endif -} - -JSValuePtr jsDOMWindowBaseXSLTProcessor(ExecState* exec, const Identifier&, const PropertySlot& slot) -{ -#if ENABLE(XSLT) - if (!static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->allowsAccessFrom(exec)) - return jsUndefined(); - return getDOMConstructor<JSXSLTProcessorConstructor>(exec); -#else - UNUSED_PARAM(exec); - UNUSED_PARAM(slot); - return jsUndefined(); -#endif -} - -void setJSDOMWindowBaseEvent(ExecState* exec, JSObject* thisObject, JSValuePtr value) -{ - if (!static_cast<JSDOMWindowBase*>(thisObject)->allowsAccessFrom(exec)) - return; - // Shadowing a built-in constructor - static_cast<JSDOMWindowBase*>(thisObject)->putDirect(Identifier(exec, "Event"), value); -} - -void setJSDOMWindowBaseAudio(ExecState* exec, JSObject* thisObject, JSValuePtr value) -{ - if (!static_cast<JSDOMWindowBase*>(thisObject)->allowsAccessFrom(exec)) - return; - // Shadowing a built-in constructor - static_cast<JSDOMWindowBase*>(thisObject)->putDirect(Identifier(exec, "Audio"), value); -} - -void setJSDOMWindowBaseImage(ExecState* exec, JSObject* thisObject, JSValuePtr value) -{ - if (!static_cast<JSDOMWindowBase*>(thisObject)->allowsAccessFrom(exec)) - return; - // Shadowing a built-in constructor - static_cast<JSDOMWindowBase*>(thisObject)->putDirect(Identifier(exec, "Image"), value); -} - -void setJSDOMWindowBaseMessageChannel(ExecState* exec, JSObject* thisObject, JSValuePtr value) -{ - if (!static_cast<JSDOMWindowBase*>(thisObject)->allowsAccessFrom(exec)) - return; - // Shadowing a built-in constructor - static_cast<JSDOMWindowBase*>(thisObject)->putDirect(Identifier(exec, "MessageChannel"), value); -} - -void setJSDOMWindowBaseOption(ExecState* exec, JSObject* thisObject, JSValuePtr value) -{ - if (!static_cast<JSDOMWindowBase*>(thisObject)->allowsAccessFrom(exec)) - return; - // Shadowing a built-in constructor - static_cast<JSDOMWindowBase*>(thisObject)->putDirect(Identifier(exec, "Option"), value); -} - -void setJSDOMWindowBaseWorker(ExecState* exec, JSObject* thisObject, JSValuePtr value) -{ - if (!static_cast<JSDOMWindowBase*>(thisObject)->allowsAccessFrom(exec)) - return; - // Shadowing a built-in constructor - static_cast<JSDOMWindowBase*>(thisObject)->putDirect(Identifier(exec, "Worker"), value); -} - -void setJSDOMWindowBaseWebKitCSSMatrix(ExecState* exec, JSObject* thisObject, JSValuePtr value) -{ - if (!static_cast<JSDOMWindowBase*>(thisObject)->allowsAccessFrom(exec)) - return; - // Shadowing a built-in constructor - static_cast<JSDOMWindowBase*>(thisObject)->putDirect(Identifier(exec, "WebKitCSSMatrix"), value); -} - -void setJSDOMWindowBaseWebKitPoint(ExecState* exec, JSObject* thisObject, JSValuePtr value) -{ - if (!static_cast<JSDOMWindowBase*>(thisObject)->allowsAccessFrom(exec)) - return; - // Shadowing a built-in constructor - static_cast<JSDOMWindowBase*>(thisObject)->putDirect(Identifier(exec, "WebKitPoint"), value); -} - -void setJSDOMWindowBaseXMLHttpRequest(ExecState* exec, JSObject* thisObject, JSValuePtr value) -{ - if (!static_cast<JSDOMWindowBase*>(thisObject)->allowsAccessFrom(exec)) - return; - // Shadowing a built-in constructor - static_cast<JSDOMWindowBase*>(thisObject)->putDirect(Identifier(exec, "XMLHttpRequest"), value); -} - -void setJSDOMWindowBaseXSLTProcessor(ExecState* exec, JSObject* thisObject, JSValuePtr value) -{ - if (!static_cast<JSDOMWindowBase*>(thisObject)->allowsAccessFrom(exec)) - return; - // Shadowing a built-in constructor - static_cast<JSDOMWindowBase*>(thisObject)->putDirect(Identifier(exec, "XSLTProcessor"), value); -} - -namespace WebCore { - -JSValuePtr JSDOMWindowBase::childFrameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSDOMWindowBase::childFrameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { return toJS(exec, static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->impl()->frame()->tree()->child(AtomicString(propertyName))->domWindow()); } -JSValuePtr JSDOMWindowBase::indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) +JSValue JSDOMWindowBase::indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) { return toJS(exec, static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->impl()->frame()->tree()->child(slot.index())->domWindow()); } -JSValuePtr JSDOMWindowBase::namedItemGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSDOMWindowBase::namedItemGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { JSDOMWindowBase* thisObj = static_cast<JSDOMWindowBase*>(asObject(slot.slotBase())); Document* doc = thisObj->impl()->frame()->document(); @@ -577,25 +111,9 @@ bool JSDOMWindowBase::getOwnPropertySlot(ExecState* exec, const Identifier& prop return true; } - const HashEntry* entry = JSDOMWindowBaseTable.entry(exec, propertyName); - if (entry) { - if (entry->attributes() & Function) { - if (entry->function() == windowProtoFuncShowModalDialog) { - if (!canShowModalDialog(impl()->frame())) - return false; - } - if (allowsAccessFrom(exec)) - setUpStaticFunctionSlot(exec, entry, this, propertyName, slot); - else - slot.setUndefined(); - } else - slot.setCustom(this, entry->propertyGetter()); - return true; - } - // Do prototype lookup early so that functions and attributes in the prototype can have // precedence over the index and name getters. - JSValuePtr proto = prototype(); + JSValue proto = prototype(); if (proto.isObject()) { if (asObject(proto)->getPropertySlot(exec, propertyName, slot)) { if (!allowsAccessFrom(exec)) @@ -633,19 +151,8 @@ bool JSDOMWindowBase::getOwnPropertySlot(ExecState* exec, const Identifier& prop return Base::getOwnPropertySlot(exec, propertyName, slot); } -void JSDOMWindowBase::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot) +void JSDOMWindowBase::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { - const HashEntry* entry = JSDOMWindowBaseTable.entry(exec, propertyName); - if (entry) { - if (entry->attributes() & Function) { - if (allowsAccessFrom(exec)) - Base::put(exec, propertyName, value, slot); - return; - } - if (entry->attributes() & ReadOnly) - return; - } - if (allowsAccessFrom(exec)) Base::put(exec, propertyName, value, slot); } @@ -692,6 +199,9 @@ ExecState* JSDOMWindowBase::globalExec() bool JSDOMWindowBase::supportsProfiling() const { +#if !ENABLE(JAVASCRIPT_DEBUGGER) + return false; +#else Frame* frame = impl()->frame(); if (!frame) return false; @@ -701,6 +211,7 @@ bool JSDOMWindowBase::supportsProfiling() const return false; return page->inspectorController()->profilerEnabled(); +#endif } bool JSDOMWindowBase::shouldInterruptScript() const @@ -721,21 +232,11 @@ bool JSDOMWindowBase::shouldInterruptScript() const return page->chrome()->shouldInterruptJavaScript(); } -void JSDOMWindowBase::clearHelperObjectProperties() +void JSDOMWindowBase::willRemoveFromWindowShell() { setCurrentEvent(0); } -void JSDOMWindowBase::clear() -{ - JSLock lock(false); - - if (d()->returnValueSlot && !*d()->returnValueSlot) - *d()->returnValueSlot = getDirect(Identifier(globalExec(), "returnValue")); - - clearHelperObjectProperties(); -} - JSObject* JSDOMWindowBase::toThisObject(ExecState*) const { return shell(); @@ -757,137 +258,7 @@ JSGlobalData* JSDOMWindowBase::commonJSGlobalData() return globalData; } -} // namespace WebCore - -using namespace WebCore; - -JSValuePtr windowProtoFuncOpen(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args) -{ - JSDOMWindow* window = toJSDOMWindow(thisValue); - if (!window) - return throwError(exec, TypeError); - if (!window->allowsAccessFrom(exec)) - return jsUndefined(); - - Frame* frame = window->impl()->frame(); - if (!frame) - return jsUndefined(); - Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); - if (!activeFrame) - return jsUndefined(); - - Page* page = frame->page(); - - String urlString = valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, 0)); - AtomicString frameName = args.at(exec, 1).isUndefinedOrNull() ? "_blank" : AtomicString(args.at(exec, 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 JSDOMWindow* targetedWindow = toJSDOMWindow(frame); - if (!completedURL.isEmpty() && (!protocolIs(completedURL, "javascript") || (targetedWindow && targetedWindow->allowsAccessFrom(exec)))) { - bool userGesture = activeFrame->script()->processingUserGesture(); - frame->loader()->scheduleLocationChange(completedURL, activeFrame->loader()->outgoingReferrer(), !activeFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture); - } - return toJS(exec, frame->domWindow()); - } - - // In the case of a named frame or a new window, we'll use the createWindow() helper - WindowFeatures windowFeatures(valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, 2))); - FloatRect windowRect(windowFeatures.xSet ? windowFeatures.x : 0, windowFeatures.ySet ? windowFeatures.y : 0, - windowFeatures.widthSet ? windowFeatures.width : 0, windowFeatures.heightSet ? windowFeatures.height : 0); - DOMWindow::adjustWindowRect(screenAvailableRect(page ? page->mainFrame()->view() : 0), 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, noValue()); - - if (!frame) - return jsUndefined(); - - return toJS(exec, frame->domWindow()); // global object -} - -JSValuePtr windowProtoFuncShowModalDialog(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args) -{ - JSDOMWindow* window = toJSDOMWindow(thisValue); - if (!window) - return throwError(exec, TypeError); - if (!window->allowsAccessFrom(exec)) - return jsUndefined(); - - Frame* frame = window->impl()->frame(); - if (!frame) - return jsUndefined(); - - return showModalDialog(exec, frame, valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, 0)), args.at(exec, 1), valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, 2))); -} - -JSValuePtr windowProtoFuncNotImplemented(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&) -{ - if (!toJSDOMWindow(thisValue)) - return throwError(exec, TypeError); - return jsUndefined(); -} - -namespace WebCore { - -void JSDOMWindowBase::setReturnValueSlot(JSValuePtr* slot) -{ - d()->returnValueSlot = slot; -} - -////////////////////// timeouts //////////////////////// - -int JSDOMWindowBase::installTimeout(ScheduledAction* a, int t, bool singleShot) -{ - return DOMTimer::install(scriptExecutionContext(), a, t, singleShot); -} - -int JSDOMWindowBase::installTimeout(const UString& handler, int t, bool singleShot) -{ - return installTimeout(new ScheduledAction(handler), t, singleShot); -} - -int JSDOMWindowBase::installTimeout(ExecState* exec, JSValuePtr func, const ArgList& args, int t, bool singleShot) -{ - return installTimeout(new ScheduledAction(exec, func, args), t, singleShot); -} - -void JSDOMWindowBase::removeTimeout(int timeoutId) -{ - DOMTimer::removeById(scriptExecutionContext(), timeoutId); -} - -void JSDOMWindowBase::disconnectFrame() -{ -} - -JSValuePtr toJS(ExecState*, DOMWindow* domWindow) +JSValue toJS(ExecState*, DOMWindow* domWindow) { if (!domWindow) return jsNull(); @@ -904,7 +275,7 @@ JSDOMWindow* toJSDOMWindow(Frame* frame) return frame->script()->windowShell()->window(); } -JSDOMWindow* toJSDOMWindow(JSValuePtr value) +JSDOMWindow* toJSDOMWindow(JSValue value) { if (!value.isObject()) return 0; diff --git a/WebCore/bindings/js/JSDOMWindowBase.h b/WebCore/bindings/js/JSDOMWindowBase.h index ef87f20..6d93196 100644 --- a/WebCore/bindings/js/JSDOMWindowBase.h +++ b/WebCore/bindings/js/JSDOMWindowBase.h @@ -34,10 +34,8 @@ namespace WebCore { class Frame; class JSDOMWindow; class JSDOMWindowShell; - class JSProtectedEventListener; class JSLocation; class JSEventListener; - class ScheduledAction; class SecurityOrigin; class JSDOMWindowBasePrivate; @@ -45,32 +43,20 @@ namespace WebCore { // This is the only WebCore JS binding which does not inherit from DOMObject class JSDOMWindowBase : public JSDOMGlobalObject { typedef JSDOMGlobalObject Base; - - friend class ScheduledAction; protected: JSDOMWindowBase(PassRefPtr<JSC::Structure>, PassRefPtr<DOMWindow>, JSDOMWindowShell*); public: - virtual ~JSDOMWindowBase(); - void updateDocument(); DOMWindow* impl() const { return d()->impl.get(); } virtual ScriptExecutionContext* scriptExecutionContext() const; - void disconnectFrame(); - virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&); - virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValuePtr, JSC::PutPropertySlot&); - - int installTimeout(const JSC::UString& handler, int t, bool singleShot); - int installTimeout(JSC::ExecState*, JSC::JSValuePtr function, const JSC::ArgList& args, int t, bool singleShot); - void removeTimeout(int timeoutId); + virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); - void clear(); - - // Set a place to put a dialog return value when the window is cleared. - void setReturnValueSlot(JSC::JSValuePtr* slot); + // Called just before removing this window from the JSDOMWindowShell. + void willRemoveFromWindowShell(); virtual const JSC::ClassInfo* classInfo() const { return &s_info; } static const JSC::ClassInfo s_info; @@ -100,17 +86,12 @@ namespace WebCore { JSDOMWindowBaseData(PassRefPtr<DOMWindow>, JSDOMWindowShell*); RefPtr<DOMWindow> impl; - - JSC::JSValuePtr* returnValueSlot; JSDOMWindowShell* shell; }; - static JSC::JSValuePtr childFrameGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); - static JSC::JSValuePtr indexGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); - static JSC::JSValuePtr namedItemGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); - - void clearHelperObjectProperties(); - int installTimeout(ScheduledAction*, int interval, bool singleShot); + static JSC::JSValue childFrameGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); + static JSC::JSValue indexGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); + static JSC::JSValue namedItemGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); bool allowsAccessFromPrivate(const JSC::JSGlobalObject*) const; String crossDomainAccessErrorMessage(const JSC::JSGlobalObject*) const; @@ -119,11 +100,11 @@ namespace WebCore { }; // Returns a JSDOMWindow or jsNull() - JSC::JSValuePtr toJS(JSC::ExecState*, DOMWindow*); + JSC::JSValue toJS(JSC::ExecState*, DOMWindow*); // Returns JSDOMWindow or 0 JSDOMWindow* toJSDOMWindow(Frame*); - JSDOMWindow* toJSDOMWindow(JSC::JSValuePtr); + JSDOMWindow* toJSDOMWindow(JSC::JSValue); } // namespace WebCore diff --git a/WebCore/bindings/js/JSDOMWindowCustom.cpp b/WebCore/bindings/js/JSDOMWindowCustom.cpp index 703ad8a..b8c30c7 100644 --- a/WebCore/bindings/js/JSDOMWindowCustom.cpp +++ b/WebCore/bindings/js/JSDOMWindowCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009 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 @@ -25,17 +25,39 @@ #include "DOMWindow.h" #include "Document.h" #include "ExceptionCode.h" +#include "FloatRect.h" #include "Frame.h" +#include "FrameLoadRequest.h" #include "FrameLoader.h" #include "FrameTree.h" +#include "FrameView.h" +#include "History.h" +#include "JSAudioConstructor.h" #include "JSDOMWindowShell.h" +#include "JSEvent.h" #include "JSEventListener.h" +#include "JSHistory.h" +#include "JSImageConstructor.h" +#include "JSLocation.h" +#include "JSMessageChannelConstructor.h" #include "JSMessagePort.h" +#include "JSOptionConstructor.h" +#include "JSWebKitCSSMatrixConstructor.h" +#include "JSWebKitPointConstructor.h" +#include "JSWorkerConstructor.h" +#include "JSXMLHttpRequestConstructor.h" +#include "JSXSLTProcessorConstructor.h" +#include "Location.h" +#include "MediaPlayer.h" #include "MessagePort.h" +#include "Page.h" +#include "PlatformScreen.h" +#include "RegisteredEventListener.h" +#include "ScheduledAction.h" #include "ScriptController.h" #include "Settings.h" +#include "WindowFeatures.h" #include <runtime/JSObject.h> -#include <runtime/PrototypeFunction.h> using namespace JSC; @@ -45,6 +67,8 @@ void JSDOMWindow::mark() { Base::mark(); + markEventListeners(impl()->eventListeners()); + JSGlobalData& globalData = *Heap::heap(this)->globalData(); markDOMObjectWrapper(globalData, impl()->optionalConsole()); @@ -97,6 +121,11 @@ void JSDOMWindow::defineGetter(ExecState* exec, const Identifier& propertyName, // Only allow defining getters by frames in the same origin. if (!allowsAccessFrom(exec)) return; + + // Don't allow shadowing location using defineGetter. + if (propertyName == "location") + return; + Base::defineGetter(exec, propertyName, getterFunction); } @@ -108,7 +137,7 @@ void JSDOMWindow::defineSetter(ExecState* exec, const Identifier& propertyName, Base::defineSetter(exec, propertyName, setterFunction); } -JSValuePtr JSDOMWindow::lookupGetter(ExecState* exec, const Identifier& propertyName) +JSValue JSDOMWindow::lookupGetter(ExecState* exec, const Identifier& propertyName) { // Only allow looking-up getters by frames in the same origin. if (!allowsAccessFrom(exec)) @@ -116,7 +145,7 @@ JSValuePtr JSDOMWindow::lookupGetter(ExecState* exec, const Identifier& property return Base::lookupGetter(exec, propertyName); } -JSValuePtr JSDOMWindow::lookupSetter(ExecState* exec, const Identifier& propertyName) +JSValue JSDOMWindow::lookupSetter(ExecState* exec, const Identifier& propertyName) { // Only allow looking-up setters by frames in the same origin. if (!allowsAccessFrom(exec)) @@ -124,17 +153,41 @@ JSValuePtr JSDOMWindow::lookupSetter(ExecState* exec, const Identifier& property return Base::lookupSetter(exec, propertyName); } -void JSDOMWindow::setLocation(ExecState* exec, JSValuePtr value) +// Custom Attributes + +JSValue JSDOMWindow::history(ExecState* exec) const +{ + History* history = impl()->history(); + if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), history)) + return wrapper; + + JSHistory* jsHistory = new (exec) JSHistory(getDOMStructure<JSHistory>(exec, const_cast<JSDOMWindow*>(this)), history); + cacheDOMObjectWrapper(exec->globalData(), history, jsHistory); + return jsHistory; +} + +JSValue JSDOMWindow::location(ExecState* exec) const { - Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); - if (!activeFrame) + Location* location = impl()->location(); + if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), location)) + return wrapper; + + JSLocation* jsLocation = new (exec) JSLocation(getDOMStructure<JSLocation>(exec, const_cast<JSDOMWindow*>(this)), location); + cacheDOMObjectWrapper(exec->globalData(), location, jsLocation); + return jsLocation; +} + +void JSDOMWindow::setLocation(ExecState* exec, JSValue value) +{ + Frame* lexicalFrame = toLexicalFrame(exec); + if (!lexicalFrame) return; #if ENABLE(DASHBOARD_SUPPORT) // 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 = activeFrame->settings()) { - if (settings->usesDashboardBackwardCompatibilityMode() && !activeFrame->tree()->parent()) { + if (Settings* settings = lexicalFrame->settings()) { + if (settings->usesDashboardBackwardCompatibilityMode() && !lexicalFrame->tree()->parent()) { if (allowsAccessFrom(exec)) putDirect(Identifier(exec, "location"), value); return; @@ -142,81 +195,341 @@ void JSDOMWindow::setLocation(ExecState* exec, JSValuePtr value) } #endif - if (!activeFrame->loader()->shouldAllowNavigation(impl()->frame())) + Frame* frame = impl()->frame(); + ASSERT(frame); + + if (!shouldAllowNavigation(exec, frame)) + return; + + KURL url = completeURL(exec, value.toString(exec)); + if (url.isNull()) return; - String dstUrl = activeFrame->loader()->completeURL(value.toString(exec)).string(); - if (!protocolIs(dstUrl, "javascript") || allowsAccessFrom(exec)) { - bool userGesture = activeFrame->script()->processingUserGesture(); + + if (!protocolIsJavaScript(url) || allowsAccessFrom(exec)) { // We want a new history item if this JS was called via a user gesture - impl()->frame()->loader()->scheduleLocationChange(dstUrl, activeFrame->loader()->outgoingReferrer(), !activeFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture); + frame->loader()->scheduleLocationChange(url, lexicalFrame->loader()->outgoingReferrer(), !lexicalFrame->script()->anyPageIsProcessingUserGesture(), false, processingUserGesture(exec)); } } -JSValuePtr JSDOMWindow::postMessage(ExecState* exec, const ArgList& args) +JSValue JSDOMWindow::crypto(ExecState*) const { - DOMWindow* window = impl(); - - DOMWindow* source = asJSDOMWindow(exec->dynamicGlobalObject())->impl(); - String message = args.at(exec, 0).toString(exec); + return jsUndefined(); +} - if (exec->hadException()) +JSValue JSDOMWindow::event(ExecState* exec) const +{ + Event* event = currentEvent(); + if (!event) return jsUndefined(); + return toJS(exec, event); +} + +JSValue JSDOMWindow::image(ExecState* exec) const +{ + return getDOMConstructor<JSImageConstructor>(exec, this); +} - MessagePort* messagePort = (args.size() == 2) ? 0 : toMessagePort(args.at(exec, 1)); +JSValue JSDOMWindow::option(ExecState* exec) const +{ + return getDOMConstructor<JSOptionConstructor>(exec, this); +} - String targetOrigin = valueToStringWithUndefinedOrNullCheck(exec, args.at(exec, (args.size() == 2) ? 1 : 2)); - if (exec->hadException()) +#if ENABLE(VIDEO) +JSValue JSDOMWindow::audio(ExecState* exec) const +{ + if (!MediaPlayer::isAvailable()) return jsUndefined(); + return getDOMConstructor<JSAudioConstructor>(exec, this); +} +#endif - ExceptionCode ec = 0; - window->postMessage(message, messagePort, targetOrigin, source, ec); - setDOMException(exec, ec); +JSValue JSDOMWindow::webKitPoint(ExecState* exec) const +{ + return getDOMConstructor<JSWebKitPointConstructor>(exec); +} - return jsUndefined(); +JSValue JSDOMWindow::webKitCSSMatrix(ExecState* exec) const +{ + return getDOMConstructor<JSWebKitCSSMatrixConstructor>(exec); +} + +JSValue JSDOMWindow::xmlHttpRequest(ExecState* exec) const +{ + return getDOMConstructor<JSXMLHttpRequestConstructor>(exec, this); +} + +#if ENABLE(XSLT) +JSValue JSDOMWindow::xsltProcessor(ExecState* exec) const +{ + return getDOMConstructor<JSXSLTProcessorConstructor>(exec); +} +#endif + +#if ENABLE(CHANNEL_MESSAGING) +JSValue JSDOMWindow::messageChannel(ExecState* exec) const +{ + return getDOMConstructor<JSMessageChannelConstructor>(exec, this); +} +#endif + +#if ENABLE(WORKERS) +JSValue JSDOMWindow::worker(ExecState* exec) const +{ + return getDOMConstructor<JSWorkerConstructor>(exec); } +#endif + +// Custom functions + +// Helper for window.open() and window.showModalDialog() +static Frame* createWindow(ExecState* exec, Frame* lexicalFrame, Frame* dynamicFrame, + Frame* openerFrame, const String& url, const String& frameName, + const WindowFeatures& windowFeatures, JSValue dialogArgs) +{ + ASSERT(lexicalFrame); + ASSERT(dynamicFrame); + + ResourceRequest request; + + // For whatever reason, Firefox uses the dynamicGlobalObject to determine + // the outgoingReferrer. We replicate that behavior here. + String referrer = dynamicFrame->loader()->outgoingReferrer(); + request.setHTTPReferrer(referrer); + FrameLoader::addHTTPOriginIfNeeded(request, dynamicFrame->loader()->outgoingOrigin()); + FrameLoadRequest frameRequest(request, frameName); + + // 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; + // We pass in the opener frame here so it can be used for looking up the frame name, in case the active frame + // is different from the opener frame, and the name references a frame relative to the opener frame, for example + // "_self" or "_parent". + Frame* newFrame = lexicalFrame->loader()->createWindow(openerFrame->loader(), frameRequest, windowFeatures, created); + if (!newFrame) + return 0; + + newFrame->loader()->setOpener(openerFrame); + newFrame->loader()->setOpenedByDOM(); + + JSDOMWindow* newWindow = toJSDOMWindow(newFrame); + + if (dialogArgs) + newWindow->putDirect(Identifier(exec, "dialogArguments"), dialogArgs); + + if (!protocolIsJavaScript(url) || newWindow->allowsAccessFrom(exec)) { + KURL completedURL = url.isEmpty() ? KURL("") : completeURL(exec, url); + bool userGesture = processingUserGesture(exec); -static JSValuePtr setTimeoutOrInterval(ExecState* exec, JSDOMWindow* window, const ArgList& args, bool timeout) + if (created) + newFrame->loader()->changeLocation(completedURL, referrer, false, false, userGesture); + else if (!url.isEmpty()) + newFrame->loader()->scheduleLocationChange(completedURL.string(), referrer, !lexicalFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture); + } + + return newFrame; +} + +JSValue JSDOMWindow::open(ExecState* exec, const ArgList& args) { - JSValuePtr v = args.at(exec, 0); - int delay = args.at(exec, 1).toInt32(exec); - if (v.isString()) - return jsNumber(exec, window->installTimeout(asString(v)->value(), delay, timeout)); - CallData callData; - if (v.getCallData(callData) == CallTypeNone) + Frame* frame = impl()->frame(); + if (!frame) + return jsUndefined(); + Frame* lexicalFrame = toLexicalFrame(exec); + if (!lexicalFrame) return jsUndefined(); - ArgList argsTail; - args.getSlice(2, argsTail); - return jsNumber(exec, window->installTimeout(exec, v, argsTail, delay, timeout)); + Frame* dynamicFrame = toDynamicFrame(exec); + if (!dynamicFrame) + return jsUndefined(); + + Page* page = frame->page(); + + String urlString = valueToStringWithUndefinedOrNullCheck(exec, args.at(0)); + AtomicString frameName = args.at(1).isUndefinedOrNull() ? "_blank" : AtomicString(args.at(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 (!DOMWindow::allowPopUp(dynamicFrame) && (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 (!shouldAllowNavigation(exec, frame)) + return jsUndefined(); + + String completedURL; + if (!urlString.isEmpty()) + completedURL = completeURL(exec, urlString).string(); + + const JSDOMWindow* targetedWindow = toJSDOMWindow(frame); + if (!completedURL.isEmpty() && (!protocolIsJavaScript(completedURL) || (targetedWindow && targetedWindow->allowsAccessFrom(exec)))) { + bool userGesture = processingUserGesture(exec); + + // For whatever reason, Firefox uses the dynamicGlobalObject to + // determine the outgoingReferrer. We replicate that behavior + // here. + String referrer = dynamicFrame->loader()->outgoingReferrer(); + + frame->loader()->scheduleLocationChange(completedURL, referrer, !lexicalFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture); + } + return toJS(exec, frame->domWindow()); + } + + // In the case of a named frame or a new window, we'll use the createWindow() helper + WindowFeatures windowFeatures(valueToStringWithUndefinedOrNullCheck(exec, args.at(2))); + FloatRect windowRect(windowFeatures.xSet ? windowFeatures.x : 0, windowFeatures.ySet ? windowFeatures.y : 0, + windowFeatures.widthSet ? windowFeatures.width : 0, windowFeatures.heightSet ? windowFeatures.height : 0); + DOMWindow::adjustWindowRect(screenAvailableRect(page ? page->mainFrame()->view() : 0), windowRect, windowRect); + + windowFeatures.x = windowRect.x(); + windowFeatures.y = windowRect.y(); + windowFeatures.height = windowRect.height(); + windowFeatures.width = windowRect.width(); + + frame = createWindow(exec, lexicalFrame, dynamicFrame, frame, urlString, frameName, windowFeatures, JSValue()); + + if (!frame) + return jsUndefined(); + + return toJS(exec, frame->domWindow()); } -JSValuePtr JSDOMWindow::setTimeout(ExecState* exec, const ArgList& args) +JSValue JSDOMWindow::showModalDialog(ExecState* exec, const ArgList& args) { - return setTimeoutOrInterval(exec, this, args, true); + Frame* frame = impl()->frame(); + if (!frame) + return jsUndefined(); + Frame* lexicalFrame = toLexicalFrame(exec); + if (!lexicalFrame) + return jsUndefined(); + Frame* dynamicFrame = toDynamicFrame(exec); + if (!dynamicFrame) + return jsUndefined(); + + if (!DOMWindow::canShowModalDialogNow(frame) || !DOMWindow::allowPopUp(dynamicFrame)) + return jsUndefined(); + + String url = valueToStringWithUndefinedOrNullCheck(exec, args.at(0)); + JSValue dialogArgs = args.at(1); + String featureArgs = valueToStringWithUndefinedOrNullCheck(exec, args.at(2)); + + HashMap<String, String> features; + DOMWindow::parseModalDialogFeatures(featureArgs, features); + + 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"); + + 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, lexicalFrame, dynamicFrame, frame, url, "", wargs, dialogArgs); + if (!dialogFrame) + return jsUndefined(); + + JSDOMWindow* dialogWindow = toJSDOMWindow(dialogFrame); + dialogFrame->page()->chrome()->runModal(); + + return dialogWindow->getDirect(Identifier(exec, "returnValue")); } -JSValuePtr JSDOMWindow::clearTimeout(ExecState* exec, const ArgList& args) +JSValue JSDOMWindow::postMessage(ExecState* exec, const ArgList& args) { - removeTimeout(args.at(exec, 0).toInt32(exec)); + DOMWindow* window = impl(); + + DOMWindow* source = asJSDOMWindow(exec->lexicalGlobalObject())->impl(); + String message = args.at(0).toString(exec); + + if (exec->hadException()) + return jsUndefined(); + + MessagePort* messagePort = (args.size() == 2) ? 0 : toMessagePort(args.at(1)); + + String targetOrigin = valueToStringWithUndefinedOrNullCheck(exec, args.at((args.size() == 2) ? 1 : 2)); + if (exec->hadException()) + return jsUndefined(); + + ExceptionCode ec = 0; + window->postMessage(message, messagePort, targetOrigin, source, ec); + setDOMException(exec, ec); + return jsUndefined(); } -JSValuePtr JSDOMWindow::setInterval(ExecState* exec, const ArgList& args) +JSValue JSDOMWindow::setTimeout(ExecState* exec, const ArgList& args) { - return setTimeoutOrInterval(exec, this, args, false); + ScheduledAction* action = ScheduledAction::create(exec, args); + if (exec->hadException()) + return jsUndefined(); + int delay = args.at(1).toInt32(exec); + return jsNumber(exec, impl()->setTimeout(action, delay)); } -JSValuePtr JSDOMWindow::clearInterval(ExecState* exec, const ArgList& args) +JSValue JSDOMWindow::setInterval(ExecState* exec, const ArgList& args) { - removeTimeout(args.at(exec, 0).toInt32(exec)); - return jsUndefined(); + ScheduledAction* action = ScheduledAction::create(exec, args); + if (exec->hadException()) + return jsUndefined(); + int delay = args.at(1).toInt32(exec); + return jsNumber(exec, impl()->setInterval(action, delay)); } -JSValuePtr JSDOMWindow::atob(ExecState* exec, const ArgList& args) +JSValue JSDOMWindow::atob(ExecState* exec, const ArgList& args) { if (args.size() < 1) return throwError(exec, SyntaxError, "Not enough arguments"); - JSValuePtr v = args.at(exec, 0); + JSValue v = args.at(0); if (v.isNull()) return jsEmptyString(exec); @@ -237,12 +550,12 @@ JSValuePtr JSDOMWindow::atob(ExecState* exec, const ArgList& args) return jsString(exec, String(out.data(), out.size())); } -JSValuePtr JSDOMWindow::btoa(ExecState* exec, const ArgList& args) +JSValue JSDOMWindow::btoa(ExecState* exec, const ArgList& args) { if (args.size() < 1) return throwError(exec, SyntaxError, "Not enough arguments"); - JSValuePtr v = args.at(exec, 0); + JSValue v = args.at(0); if (v.isNull()) return jsEmptyString(exec); @@ -262,31 +575,31 @@ JSValuePtr JSDOMWindow::btoa(ExecState* exec, const ArgList& args) return jsString(exec, String(out.data(), out.size())); } -JSValuePtr JSDOMWindow::addEventListener(ExecState* exec, const ArgList& args) +JSValue JSDOMWindow::addEventListener(ExecState* exec, const ArgList& args) { Frame* frame = impl()->frame(); if (!frame) return jsUndefined(); - if (RefPtr<JSProtectedEventListener> listener = findOrCreateJSProtectedEventListener(exec, args.at(exec, 1))) - frame->document()->addWindowEventListener(AtomicString(args.at(exec, 0).toString(exec)), listener.release(), args.at(exec, 2).toBoolean(exec)); + if (RefPtr<JSEventListener> listener = findOrCreateJSEventListener(args.at(1))) + impl()->addEventListener(AtomicString(args.at(0).toString(exec)), listener.release(), args.at(2).toBoolean(exec)); return jsUndefined(); } -JSValuePtr JSDOMWindow::removeEventListener(ExecState* exec, const ArgList& args) +JSValue JSDOMWindow::removeEventListener(ExecState* exec, const ArgList& args) { Frame* frame = impl()->frame(); if (!frame) return jsUndefined(); - if (JSProtectedEventListener* listener = findJSProtectedEventListener(args.at(exec, 1))) - frame->document()->removeWindowEventListener(AtomicString(args.at(exec, 0).toString(exec)), listener, args.at(exec, 2).toBoolean(exec)); + if (JSEventListener* listener = findJSEventListener(args.at(1))) + impl()->removeEventListener(AtomicString(args.at(0).toString(exec)), listener, args.at(2).toBoolean(exec)); return jsUndefined(); } -DOMWindow* toDOMWindow(JSValuePtr value) +DOMWindow* toDOMWindow(JSValue value) { if (!value.isObject()) return 0; @@ -298,24 +611,4 @@ DOMWindow* toDOMWindow(JSValuePtr value) return 0; } -JSValuePtr nonCachingStaticCloseFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) -{ - return new (exec) PrototypeFunction(exec, 0, propertyName, jsDOMWindowPrototypeFunctionClose); -} - -JSValuePtr nonCachingStaticBlurFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) -{ - return new (exec) PrototypeFunction(exec, 0, propertyName, jsDOMWindowPrototypeFunctionBlur); -} - -JSValuePtr nonCachingStaticFocusFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) -{ - return new (exec) PrototypeFunction(exec, 0, propertyName, jsDOMWindowPrototypeFunctionFocus); -} - -JSValuePtr nonCachingStaticPostMessageFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) -{ - return new (exec) PrototypeFunction(exec, 2, propertyName, jsDOMWindowPrototypeFunctionPostMessage); -} - } // namespace WebCore diff --git a/WebCore/bindings/js/JSDOMWindowCustom.h b/WebCore/bindings/js/JSDOMWindowCustom.h index 73a9656..52ef4a0 100644 --- a/WebCore/bindings/js/JSDOMWindowCustom.h +++ b/WebCore/bindings/js/JSDOMWindowCustom.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reseved. + * Copyright (C) 2008, 2009 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 @@ -21,6 +21,7 @@ #include "JSDOMWindow.h" #include "JSDOMWindowShell.h" +#include <runtime/PrototypeFunction.h> #include <wtf/AlwaysInline.h> namespace WebCore { @@ -35,10 +36,11 @@ inline const JSDOMWindow* asJSDOMWindow(const JSC::JSGlobalObject* globalObject) return static_cast<const JSDOMWindow*>(globalObject); } -JSC::JSValuePtr nonCachingStaticCloseFunctionGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); -JSC::JSValuePtr nonCachingStaticBlurFunctionGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); -JSC::JSValuePtr nonCachingStaticFocusFunctionGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); -JSC::JSValuePtr nonCachingStaticPostMessageFunctionGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); +template<JSC::NativeFunction nativeFunction, int length> +JSC::JSValue nonCachingStaticFunctionGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, const JSC::PropertySlot&) +{ + return new (exec) JSC::PrototypeFunction(exec, length, propertyName, nativeFunction); +} ALWAYS_INLINE bool JSDOMWindow::customGetOwnPropertySlot(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::PropertySlot& slot) { @@ -59,7 +61,7 @@ ALWAYS_INLINE bool JSDOMWindow::customGetOwnPropertySlot(JSC::ExecState* exec, c } entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); if (entry && (entry->attributes() & JSC::Function) && entry->function() == jsDOMWindowPrototypeFunctionClose) { - slot.setCustom(this, nonCachingStaticCloseFunctionGetter); + slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>); return true; } @@ -88,22 +90,27 @@ ALWAYS_INLINE bool JSDOMWindow::customGetOwnPropertySlot(JSC::ExecState* exec, c if (entry->attributes() & JSC::Function) { if (entry->function() == jsDOMWindowPrototypeFunctionBlur) { if (!allowsAccess) { - slot.setCustom(this, nonCachingStaticBlurFunctionGetter); + slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionBlur, 0>); return true; } } else if (entry->function() == jsDOMWindowPrototypeFunctionClose) { if (!allowsAccess) { - slot.setCustom(this, nonCachingStaticCloseFunctionGetter); + slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>); return true; } } else if (entry->function() == jsDOMWindowPrototypeFunctionFocus) { if (!allowsAccess) { - slot.setCustom(this, nonCachingStaticFocusFunctionGetter); + slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionFocus, 0>); return true; } } else if (entry->function() == jsDOMWindowPrototypeFunctionPostMessage) { if (!allowsAccess) { - slot.setCustom(this, nonCachingStaticPostMessageFunctionGetter); + slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionPostMessage, 2>); + return true; + } + } else if (entry->function() == jsDOMWindowPrototypeFunctionShowModalDialog) { + if (!DOMWindow::canShowModalDialog(impl()->frame())) { + slot.setUndefined(); return true; } } @@ -121,7 +128,7 @@ ALWAYS_INLINE bool JSDOMWindow::customGetOwnPropertySlot(JSC::ExecState* exec, c return false; } -inline bool JSDOMWindow::customPut(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSValuePtr value, JSC::PutPropertySlot& slot) +inline bool JSDOMWindow::customPut(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSValue value, JSC::PutPropertySlot& slot) { if (!impl()->frame()) return true; @@ -144,8 +151,6 @@ inline bool JSDOMWindow::customPut(JSC::ExecState* exec, const JSC::Identifier& return false; } - - inline bool JSDOMWindowBase::allowsAccessFrom(const JSGlobalObject* other) const { if (allowsAccessFromPrivate(other)) @@ -154,7 +159,7 @@ inline bool JSDOMWindowBase::allowsAccessFrom(const JSGlobalObject* other) const return false; } - inline bool JSDOMWindowBase::allowsAccessFrom(JSC::ExecState* exec) const +inline bool JSDOMWindowBase::allowsAccessFrom(JSC::ExecState* exec) const { if (allowsAccessFromPrivate(exec->lexicalGlobalObject())) return true; @@ -183,12 +188,6 @@ ALWAYS_INLINE bool JSDOMWindowBase::allowsAccessFromPrivate(const JSGlobalObject if (originWindow == targetWindow) return true; - // 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 (!originWindow->impl()->document()) - return true; - const SecurityOrigin* originSecurityOrigin = originWindow->impl()->securityOrigin(); const SecurityOrigin* targetSecurityOrigin = targetWindow->impl()->securityOrigin(); diff --git a/WebCore/bindings/js/JSDOMWindowShell.cpp b/WebCore/bindings/js/JSDOMWindowShell.cpp index f14c2f7..1bf478b 100644 --- a/WebCore/bindings/js/JSDOMWindowShell.cpp +++ b/WebCore/bindings/js/JSDOMWindowShell.cpp @@ -88,12 +88,12 @@ bool JSDOMWindowShell::getOwnPropertySlot(ExecState* exec, const Identifier& pro return m_window->getOwnPropertySlot(exec, propertyName, slot); } -void JSDOMWindowShell::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot) +void JSDOMWindowShell::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { m_window->put(exec, propertyName, value, slot); } -void JSDOMWindowShell::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValuePtr value, unsigned attributes) +void JSDOMWindowShell::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes) { m_window->putWithAttributes(exec, propertyName, value, attributes); } @@ -123,12 +123,12 @@ void JSDOMWindowShell::defineSetter(ExecState* exec, const Identifier& propertyN m_window->defineSetter(exec, propertyName, setterFunction); } -JSValuePtr JSDOMWindowShell::lookupGetter(ExecState* exec, const Identifier& propertyName) +JSValue JSDOMWindowShell::lookupGetter(ExecState* exec, const Identifier& propertyName) { return m_window->lookupGetter(exec, propertyName); } -JSValuePtr JSDOMWindowShell::lookupSetter(ExecState* exec, const Identifier& propertyName) +JSValue JSDOMWindowShell::lookupSetter(ExecState* exec, const Identifier& propertyName) { return m_window->lookupSetter(exec, propertyName); } @@ -147,16 +147,6 @@ DOMWindow* JSDOMWindowShell::impl() const return m_window->impl(); } -void JSDOMWindowShell::disconnectFrame() -{ - m_window->disconnectFrame(); -} - -void JSDOMWindowShell::clear() -{ - m_window->clear(); -} - void* JSDOMWindowShell::operator new(size_t size) { return JSDOMWindow::commonJSGlobalData()->heap.allocate(size); @@ -166,7 +156,7 @@ void* JSDOMWindowShell::operator new(size_t size) // Conversion methods // ---- -JSValuePtr toJS(ExecState*, Frame* frame) +JSValue toJS(ExecState*, Frame* frame) { if (!frame) return jsNull(); diff --git a/WebCore/bindings/js/JSDOMWindowShell.h b/WebCore/bindings/js/JSDOMWindowShell.h index 931a256..6f21892 100644 --- a/WebCore/bindings/js/JSDOMWindowShell.h +++ b/WebCore/bindings/js/JSDOMWindowShell.h @@ -55,12 +55,10 @@ namespace WebCore { static const JSC::ClassInfo s_info; DOMWindow* impl() const; - void disconnectFrame(); - void clear(); void* operator new(size_t); - static PassRefPtr<JSC::Structure> createStructure(JSC::JSValuePtr prototype) + static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) { return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType)); } @@ -69,22 +67,22 @@ namespace WebCore { virtual void mark(); virtual JSC::UString className() const; virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&); - virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValuePtr, JSC::PutPropertySlot&); - virtual void putWithAttributes(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValuePtr, unsigned attributes); + virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); + virtual void putWithAttributes(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, unsigned attributes); virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier& propertyName); virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&); virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier& propertyName, unsigned& attributes) const; virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction); virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction); - virtual JSC::JSValuePtr lookupGetter(JSC::ExecState*, const JSC::Identifier& propertyName); - virtual JSC::JSValuePtr lookupSetter(JSC::ExecState*, const JSC::Identifier& propertyName); + virtual JSC::JSValue lookupGetter(JSC::ExecState*, const JSC::Identifier& propertyName); + virtual JSC::JSValue lookupSetter(JSC::ExecState*, const JSC::Identifier& propertyName); virtual JSC::JSObject* unwrappedObject(); virtual const JSC::ClassInfo* classInfo() const { return &s_info; } JSDOMWindow* m_window; }; - JSC::JSValuePtr toJS(JSC::ExecState*, Frame*); + JSC::JSValue toJS(JSC::ExecState*, Frame*); JSDOMWindowShell* toJSDOMWindowShell(Frame*); } // namespace WebCore diff --git a/WebCore/bindings/js/JSDatabaseCustom.cpp b/WebCore/bindings/js/JSDatabaseCustom.cpp index f0f2b69..af3b066 100644 --- a/WebCore/bindings/js/JSDatabaseCustom.cpp +++ b/WebCore/bindings/js/JSDatabaseCustom.cpp @@ -47,17 +47,17 @@ namespace WebCore { using namespace JSC; -JSValuePtr JSDatabase::changeVersion(ExecState* exec, const ArgList& args) +JSValue JSDatabase::changeVersion(ExecState* exec, const ArgList& args) { - String oldVersion = args.at(exec, 0).toString(exec); - String newVersion = args.at(exec, 1).toString(exec); + String oldVersion = args.at(0).toString(exec); + String newVersion = args.at(1).toString(exec); Frame* frame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); if (!frame) return jsUndefined(); JSObject* object; - if (!(object = args.at(exec, 2).getObject())) { + if (!(object = args.at(2).getObject())) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); } @@ -65,8 +65,8 @@ JSValuePtr JSDatabase::changeVersion(ExecState* exec, const ArgList& args) RefPtr<SQLTransactionCallback> callback(JSCustomSQLTransactionCallback::create(object, frame)); RefPtr<SQLTransactionErrorCallback> errorCallback; - if (!args.at(exec, 3).isNull()) { - if (!(object = args.at(exec, 3).getObject())) { + if (!args.at(3).isNull()) { + if (!(object = args.at(3).getObject())) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); } @@ -75,8 +75,8 @@ JSValuePtr JSDatabase::changeVersion(ExecState* exec, const ArgList& args) } RefPtr<VoidCallback> successCallback; - if (!args.at(exec, 4).isNull()) { - successCallback = toVoidCallback(exec, args.at(exec, 4)); + if (!args.at(4).isNull()) { + successCallback = toVoidCallback(exec, args.at(4)); if (!successCallback) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); @@ -88,11 +88,11 @@ JSValuePtr JSDatabase::changeVersion(ExecState* exec, const ArgList& args) return jsUndefined(); } -JSValuePtr JSDatabase::transaction(ExecState* exec, const ArgList& args) +JSValue JSDatabase::transaction(ExecState* exec, const ArgList& args) { JSObject* object; - if (!(object = args.at(exec, 0).getObject())) { + if (!(object = args.at(0).getObject())) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); } @@ -104,8 +104,8 @@ JSValuePtr JSDatabase::transaction(ExecState* exec, const ArgList& args) RefPtr<SQLTransactionCallback> callback(JSCustomSQLTransactionCallback::create(object, frame)); RefPtr<SQLTransactionErrorCallback> errorCallback; - if (args.size() > 1 && !args.at(exec, 1).isNull()) { - if (!(object = args.at(exec, 1).getObject())) { + if (args.size() > 1 && !args.at(1).isNull()) { + if (!(object = args.at(1).getObject())) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); } @@ -114,8 +114,8 @@ JSValuePtr JSDatabase::transaction(ExecState* exec, const ArgList& args) } RefPtr<VoidCallback> successCallback; - if (args.size() > 2 && !args.at(exec, 2).isNull()) { - successCallback = toVoidCallback(exec, args.at(exec, 2)); + if (args.size() > 2 && !args.at(2).isNull()) { + successCallback = toVoidCallback(exec, args.at(2)); if (!successCallback) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); diff --git a/WebCore/bindings/js/JSDocumentCustom.cpp b/WebCore/bindings/js/JSDocumentCustom.cpp index c432aea..956327a 100644 --- a/WebCore/bindings/js/JSDocumentCustom.cpp +++ b/WebCore/bindings/js/JSDocumentCustom.cpp @@ -27,6 +27,7 @@ #include "JSDOMWindowCustom.h" #include "JSHTMLDocument.h" #include "JSLocation.h" +#include "Location.h" #include "ScriptController.h" #if ENABLE(SVG) @@ -45,16 +46,23 @@ void JSDocument::mark() markActiveObjectsForContext(*Heap::heap(this)->globalData(), impl()); } -JSValuePtr JSDocument::location(ExecState* exec) const +JSValue JSDocument::location(ExecState* exec) const { Frame* frame = static_cast<Document*>(impl())->frame(); if (!frame) return jsNull(); - return toJS(exec, frame->domWindow()->location()); + Location* location = frame->domWindow()->location(); + if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), location)) + return wrapper; + + JSDOMWindow* window = static_cast<JSDOMWindow*>(exec->lexicalGlobalObject()); + JSLocation* jsLocation = new (exec) JSLocation(getDOMStructure<JSLocation>(exec, window), location); + cacheDOMObjectWrapper(exec->globalData(), location, jsLocation); + return jsLocation; } -void JSDocument::setLocation(ExecState* exec, JSValuePtr value) +void JSDocument::setLocation(ExecState* exec, JSValue value) { Frame* frame = static_cast<Document*>(impl())->frame(); if (!frame) @@ -72,7 +80,7 @@ void JSDocument::setLocation(ExecState* exec, JSValuePtr value) frame->loader()->scheduleLocationChange(str, activeFrame->loader()->outgoingReferrer(), !activeFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture); } -JSValuePtr toJS(ExecState* exec, Document* document) +JSValue toJS(ExecState* exec, Document* document) { if (!document) return jsNull(); diff --git a/WebCore/bindings/js/JSElementCustom.cpp b/WebCore/bindings/js/JSElementCustom.cpp index f5ef4be..b12c185 100644 --- a/WebCore/bindings/js/JSElementCustom.cpp +++ b/WebCore/bindings/js/JSElementCustom.cpp @@ -53,7 +53,7 @@ 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")) { + if ((element->hasTagName(iframeTag) || element->hasTagName(frameTag)) && equalIgnoringCase(name, "src") && protocolIsJavaScript(parseURL(value))) { HTMLFrameElementBase* frame = static_cast<HTMLFrameElementBase*>(element); if (!checkNodeSecurity(exec, frame->contentDocument())) return false; @@ -61,11 +61,11 @@ static inline bool allowSettingSrcToJavascriptURL(ExecState* exec, Element* elem return true; } -JSValuePtr JSElement::setAttribute(ExecState* exec, const ArgList& args) +JSValue JSElement::setAttribute(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; - AtomicString name = args.at(exec, 0).toString(exec); - AtomicString value = args.at(exec, 1).toString(exec); + AtomicString name = args.at(0).toString(exec); + AtomicString value = args.at(1).toString(exec); Element* imp = impl(); if (!allowSettingSrcToJavascriptURL(exec, imp, name, value)) @@ -76,10 +76,10 @@ JSValuePtr JSElement::setAttribute(ExecState* exec, const ArgList& args) return jsUndefined(); } -JSValuePtr JSElement::setAttributeNode(ExecState* exec, const ArgList& args) +JSValue JSElement::setAttributeNode(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; - Attr* newAttr = toAttr(args.at(exec, 0)); + Attr* newAttr = toAttr(args.at(0)); if (!newAttr) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); @@ -89,17 +89,17 @@ JSValuePtr JSElement::setAttributeNode(ExecState* exec, const ArgList& args) if (!allowSettingSrcToJavascriptURL(exec, imp, newAttr->name(), newAttr->value())) return jsUndefined(); - JSValuePtr result = toJS(exec, WTF::getPtr(imp->setAttributeNode(newAttr, ec))); + JSValue result = toJS(exec, WTF::getPtr(imp->setAttributeNode(newAttr, ec))); setDOMException(exec, ec); return result; } -JSValuePtr JSElement::setAttributeNS(ExecState* exec, const ArgList& args) +JSValue JSElement::setAttributeNS(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; - AtomicString namespaceURI = valueToStringWithNullCheck(exec, args.at(exec, 0)); - AtomicString qualifiedName = args.at(exec, 1).toString(exec); - AtomicString value = args.at(exec, 2).toString(exec); + AtomicString namespaceURI = valueToStringWithNullCheck(exec, args.at(0)); + AtomicString qualifiedName = args.at(1).toString(exec); + AtomicString value = args.at(2).toString(exec); Element* imp = impl(); if (!allowSettingSrcToJavascriptURL(exec, imp, qualifiedName, value)) @@ -110,10 +110,10 @@ JSValuePtr JSElement::setAttributeNS(ExecState* exec, const ArgList& args) return jsUndefined(); } -JSValuePtr JSElement::setAttributeNodeNS(ExecState* exec, const ArgList& args) +JSValue JSElement::setAttributeNodeNS(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; - Attr* newAttr = toAttr(args.at(exec, 0)); + Attr* newAttr = toAttr(args.at(0)); if (!newAttr) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); @@ -123,12 +123,12 @@ JSValuePtr JSElement::setAttributeNodeNS(ExecState* exec, const ArgList& args) if (!allowSettingSrcToJavascriptURL(exec, imp, newAttr->name(), newAttr->value())) return jsUndefined(); - JSValuePtr result = toJS(exec, WTF::getPtr(imp->setAttributeNodeNS(newAttr, ec))); + JSValue result = toJS(exec, WTF::getPtr(imp->setAttributeNodeNS(newAttr, ec))); setDOMException(exec, ec); return result; } -JSValuePtr toJSNewlyCreated(ExecState* exec, Element* element) +JSValue toJSNewlyCreated(ExecState* exec, Element* element) { if (!element) return jsNull(); diff --git a/WebCore/bindings/js/JSEventCustom.cpp b/WebCore/bindings/js/JSEventCustom.cpp index 613e46d..a020d74 100644 --- a/WebCore/bindings/js/JSEventCustom.cpp +++ b/WebCore/bindings/js/JSEventCustom.cpp @@ -77,12 +77,12 @@ using namespace JSC; namespace WebCore { -JSValuePtr JSEvent::clipboardData(ExecState* exec) const +JSValue JSEvent::clipboardData(ExecState* exec) const { return impl()->isClipboardEvent() ? toJS(exec, impl()->clipboardData()) : jsUndefined(); } -JSValuePtr toJS(ExecState* exec, Event* event) +JSValue toJS(ExecState* exec, Event* event) { JSLock lock(false); diff --git a/WebCore/bindings/js/JSEventListener.cpp b/WebCore/bindings/js/JSEventListener.cpp index 4c9cf0d..b9ed685 100644 --- a/WebCore/bindings/js/JSEventListener.cpp +++ b/WebCore/bindings/js/JSEventListener.cpp @@ -31,15 +31,43 @@ using namespace JSC; namespace WebCore { -void JSAbstractEventListener::handleEvent(Event* event, bool isWindowEvent) +JSEventListener::JSEventListener(JSObject* function, JSDOMGlobalObject* globalObject, bool isAttribute) + : m_jsFunction(function) + , m_globalObject(globalObject) + , m_isAttribute(isAttribute) +{ + if (!m_isAttribute && m_jsFunction) + globalObject->jsEventListeners().set(m_jsFunction, this); +} + +JSEventListener::~JSEventListener() +{ + if (!m_isAttribute && m_jsFunction && m_globalObject) + m_globalObject->jsEventListeners().remove(m_jsFunction); +} + +JSObject* JSEventListener::jsFunction() const +{ + return m_jsFunction; +} + +void JSEventListener::markJSFunction() +{ + if (m_jsFunction && !m_jsFunction->marked()) + m_jsFunction->mark(); + if (m_globalObject && !m_globalObject->marked()) + m_globalObject->mark(); +} + +void JSEventListener::handleEvent(Event* event, bool isWindowEvent) { JSLock lock(false); - JSObject* listener = function(); - if (!listener) + JSObject* jsFunction = this->jsFunction(); + if (!jsFunction) return; - JSDOMGlobalObject* globalObject = this->globalObject(); + JSDOMGlobalObject* globalObject = m_globalObject; // Null check as clearGlobalObject() can clear this and we still get called back by // xmlhttprequest objects. See http://bugs.webkit.org/show_bug.cgi?id=13275 // FIXME: Is this check still necessary? Requests are supposed to be stopped before clearGlobalObject() is called. @@ -67,18 +95,18 @@ void JSAbstractEventListener::handleEvent(Event* event, bool isWindowEvent) ExecState* exec = globalObject->globalExec(); - JSValuePtr handleEventFunction = listener->get(exec, Identifier(exec, "handleEvent")); + JSValue handleEventFunction = jsFunction->get(exec, Identifier(exec, "handleEvent")); CallData callData; CallType callType = handleEventFunction.getCallData(callData); if (callType == CallTypeNone) { - handleEventFunction = noValue(); - callType = listener->getCallData(callData); + handleEventFunction = JSValue(); + callType = jsFunction->getCallData(callData); } if (callType != CallTypeNone) { ref(); - ArgList args; + MarkedArgumentBuffer args; args.append(toJS(exec, event)); Event* savedEvent = globalObject->currentEvent(); @@ -90,18 +118,18 @@ void JSAbstractEventListener::handleEvent(Event* event, bool isWindowEvent) JSGlobalData* globalData = globalObject->globalData(); DynamicGlobalObjectScope globalObjectScope(exec, globalData->dynamicGlobalObject ? globalData->dynamicGlobalObject : globalObject); - JSValuePtr retval; + JSValue retval; if (handleEventFunction) { globalObject->globalData()->timeoutChecker.start(); - retval = call(exec, handleEventFunction, callType, callData, listener, args); + retval = call(exec, handleEventFunction, callType, callData, jsFunction, args); } else { - JSValuePtr thisValue; + JSValue thisValue; if (isWindowEvent) thisValue = globalObject->toThisObject(exec); else thisValue = toJS(exec, event->currentTarget()); globalObject->globalData()->timeoutChecker.start(); - retval = call(exec, listener, callType, callData, thisValue, args); + retval = call(exec, jsFunction, callType, callData, thisValue, args); } globalObject->globalData()->timeoutChecker.stop(); @@ -112,7 +140,7 @@ void JSAbstractEventListener::handleEvent(Event* event, bool isWindowEvent) else { if (!retval.isUndefinedOrNull() && event->storesResultAsString()) event->storeResult(retval.toString(exec)); - if (m_isInline) { + if (m_isAttribute) { bool retvalbool; if (retval.getBoolean(retvalbool) && !retvalbool) event->preventDefault(); @@ -120,106 +148,14 @@ void JSAbstractEventListener::handleEvent(Event* event, bool isWindowEvent) } if (scriptExecutionContext->isDocument()) - Document::updateDocumentsRendering(); + Document::updateStyleForAllDocuments(); deref(); } } -bool JSAbstractEventListener::virtualIsInline() const -{ - return m_isInline; -} - -// ------------------------------------------------------------------------- - -JSEventListener::JSEventListener(JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline) - : JSAbstractEventListener(isInline) - , m_listener(listener) - , m_globalObject(globalObject) -{ - if (m_listener) { - JSDOMWindow::JSListenersMap& listeners = isInline - ? globalObject->jsInlineEventListeners() : globalObject->jsEventListeners(); - listeners.set(m_listener, this); - } -} - -JSEventListener::~JSEventListener() -{ - if (m_listener && m_globalObject) { - JSDOMWindow::JSListenersMap& listeners = isInline() - ? m_globalObject->jsInlineEventListeners() : m_globalObject->jsEventListeners(); - listeners.remove(m_listener); - } -} - -JSObject* JSEventListener::function() const -{ - return m_listener; -} - -JSDOMGlobalObject* JSEventListener::globalObject() const -{ - return m_globalObject; -} - -void JSEventListener::clearGlobalObject() -{ - m_globalObject = 0; -} - -void JSEventListener::mark() -{ - if (m_listener && !m_listener->marked()) - m_listener->mark(); -} - -#ifndef NDEBUG -static WTF::RefCountedLeakCounter eventListenerCounter("EventListener"); -#endif - -// ------------------------------------------------------------------------- - -JSProtectedEventListener::JSProtectedEventListener(JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline) - : JSAbstractEventListener(isInline) - , m_listener(listener) - , m_globalObject(globalObject) -{ - if (m_listener) { - JSDOMWindow::ProtectedListenersMap& listeners = isInline - ? m_globalObject->jsProtectedInlineEventListeners() : m_globalObject->jsProtectedEventListeners(); - listeners.set(m_listener, this); - } -#ifndef NDEBUG - eventListenerCounter.increment(); -#endif -} - -JSProtectedEventListener::~JSProtectedEventListener() -{ - if (m_listener && m_globalObject) { - JSDOMWindow::ProtectedListenersMap& listeners = isInline() - ? m_globalObject->jsProtectedInlineEventListeners() : m_globalObject->jsProtectedEventListeners(); - listeners.remove(m_listener); - } -#ifndef NDEBUG - eventListenerCounter.decrement(); -#endif -} - -JSObject* JSProtectedEventListener::function() const -{ - return m_listener; -} - -JSDOMGlobalObject* JSProtectedEventListener::globalObject() const -{ - return m_globalObject; -} - -void JSProtectedEventListener::clearGlobalObject() +bool JSEventListener::virtualisAttribute() const { - m_globalObject = 0; + return m_isAttribute; } } // namespace WebCore diff --git a/WebCore/bindings/js/JSEventListener.h b/WebCore/bindings/js/JSEventListener.h index 9589001..ce34832 100644 --- a/WebCore/bindings/js/JSEventListener.h +++ b/WebCore/bindings/js/JSEventListener.h @@ -21,70 +21,39 @@ #define JSEventListener_h #include "EventListener.h" +#include "JSDOMWindow.h" #include <runtime/Protect.h> namespace WebCore { class JSDOMGlobalObject; - class JSAbstractEventListener : public EventListener { + class JSEventListener : public EventListener { public: - bool isInline() const { return m_isInline; } - - protected: - JSAbstractEventListener(bool isInline) - : m_isInline(isInline) + static PassRefPtr<JSEventListener> create(JSC::JSObject* listener, JSDOMGlobalObject* globalObject, bool isAttribute) { - } - - private: - virtual void handleEvent(Event*, bool isWindowEvent); - virtual JSDOMGlobalObject* globalObject() const = 0; - virtual bool virtualIsInline() const; - - bool m_isInline; - }; - - class JSEventListener : public JSAbstractEventListener { - public: - static PassRefPtr<JSEventListener> create(JSC::JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline) - { - return adoptRef(new JSEventListener(listener, globalObject, isInline)); + return adoptRef(new JSEventListener(listener, globalObject, isAttribute)); } virtual ~JSEventListener(); + void clearGlobalObject() { m_globalObject = 0; } - void clearGlobalObject(); - - private: - JSEventListener(JSC::JSObject* listener, JSDOMGlobalObject*, bool isInline); + // Returns true if this event listener was created for an event handler attribute, like "onload" or "onclick". + bool isAttribute() const { return m_isAttribute; } - virtual JSC::JSObject* function() const; - virtual void mark(); - virtual JSDOMGlobalObject* globalObject() const; + virtual JSC::JSObject* jsFunction() const; - JSC::JSObject* m_listener; - JSDOMGlobalObject* m_globalObject; - }; - - class JSProtectedEventListener : public JSAbstractEventListener { - public: - static PassRefPtr<JSProtectedEventListener> create(JSC::JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline) - { - return adoptRef(new JSProtectedEventListener(listener, globalObject, isInline)); - } - virtual ~JSProtectedEventListener(); - - void clearGlobalObject(); + private: + virtual void markJSFunction(); + virtual void handleEvent(Event*, bool isWindowEvent); + virtual bool virtualisAttribute() const; + void clearJSFunctionInline(); protected: - JSProtectedEventListener(JSC::JSObject* listener, JSDOMGlobalObject*, bool isInline); + JSEventListener(JSC::JSObject* function, JSDOMGlobalObject*, bool isAttribute); - mutable JSC::ProtectedPtr<JSC::JSObject> m_listener; - JSC::ProtectedPtr<JSDOMGlobalObject> m_globalObject; - - private: - virtual JSC::JSObject* function() const; - virtual JSDOMGlobalObject* globalObject() const; + mutable JSC::JSObject* m_jsFunction; + JSDOMGlobalObject* m_globalObject; + bool m_isAttribute; }; } // namespace WebCore diff --git a/WebCore/bindings/js/JSEventTarget.cpp b/WebCore/bindings/js/JSEventTarget.cpp index d9cff4a..2058098 100644 --- a/WebCore/bindings/js/JSEventTarget.cpp +++ b/WebCore/bindings/js/JSEventTarget.cpp @@ -26,7 +26,10 @@ #include "config.h" #include "JSEventTarget.h" +#include "DOMWindow.h" #include "Document.h" +#include "JSDOMWindow.h" +#include "JSDOMWindowShell.h" #include "JSEventListener.h" #include "JSMessagePort.h" #include "JSNode.h" @@ -57,7 +60,7 @@ using namespace JSC; namespace WebCore { -JSValuePtr toJS(ExecState* exec, EventTarget* target) +JSValue toJS(ExecState* exec, EventTarget* target) { if (!target) return jsNull(); @@ -71,6 +74,9 @@ JSValuePtr toJS(ExecState* exec, EventTarget* target) if (Node* node = target->toNode()) return toJS(exec, node); + if (DOMWindow* domWindow = target->toDOMWindow()) + return toJS(exec, domWindow); + if (XMLHttpRequest* xhr = target->toXMLHttpRequest()) // XMLHttpRequest is always created via JS, so we don't need to use cacheDOMObject() here. return getCachedDOMObjectWrapper(exec->globalData(), xhr); @@ -99,7 +105,7 @@ JSValuePtr toJS(ExecState* exec, EventTarget* target) return jsNull(); } -EventTarget* toEventTarget(JSC::JSValuePtr value) +EventTarget* toEventTarget(JSC::JSValue value) { #define CONVERT_TO_EVENT_TARGET(type) \ if (value.isObject(&JS##type::s_info)) \ @@ -110,6 +116,9 @@ EventTarget* toEventTarget(JSC::JSValuePtr value) CONVERT_TO_EVENT_TARGET(XMLHttpRequestUpload) CONVERT_TO_EVENT_TARGET(MessagePort) + if (value.isObject(&JSDOMWindowShell::s_info)) + return static_cast<JSDOMWindowShell*>(asObject(value))->impl(); + #if ENABLE(OFFLINE_WEB_APPLICATIONS) CONVERT_TO_EVENT_TARGET(DOMApplicationCache) #endif diff --git a/WebCore/bindings/js/JSEventTarget.h b/WebCore/bindings/js/JSEventTarget.h index 02f3734..05df056 100644 --- a/WebCore/bindings/js/JSEventTarget.h +++ b/WebCore/bindings/js/JSEventTarget.h @@ -36,8 +36,8 @@ namespace WebCore { class EventTarget; - JSC::JSValuePtr toJS(JSC::ExecState*, EventTarget*); - EventTarget* toEventTarget(JSC::JSValuePtr); + JSC::JSValue toJS(JSC::ExecState*, EventTarget*); + EventTarget* toEventTarget(JSC::JSValue); } // namespace WebCore diff --git a/WebCore/bindings/js/JSEventTargetBase.h b/WebCore/bindings/js/JSEventTargetBase.h deleted file mode 100644 index b841ee9..0000000 --- a/WebCore/bindings/js/JSEventTargetBase.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2007, 2008 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 "Event.h" -#include "EventNames.h" -#include "JSEvent.h" - -#define JS_EVENT_LISTENER_FOR_EACH_LISTENER(specificEventTarget, macro) \ - macro(specificEventTarget, OnAbort, abortEvent) \ - macro(specificEventTarget, OnBlur, blurEvent) \ - macro(specificEventTarget, OnChange, changeEvent) \ - macro(specificEventTarget, OnClick, clickEvent) \ - macro(specificEventTarget, OnContextMenu, contextmenuEvent) \ - macro(specificEventTarget, OnDblClick, dblclickEvent) \ - macro(specificEventTarget, OnError, errorEvent) \ - macro(specificEventTarget, OnFocus, focusEvent) \ - macro(specificEventTarget, OnInput, inputEvent) \ - macro(specificEventTarget, OnKeyDown, keydownEvent) \ - macro(specificEventTarget, OnKeyPress, keypressEvent) \ - macro(specificEventTarget, OnKeyUp, keyupEvent) \ - macro(specificEventTarget, OnLoad, loadEvent) \ - macro(specificEventTarget, OnMouseDown, mousedownEvent) \ - macro(specificEventTarget, OnMouseMove, mousemoveEvent) \ - macro(specificEventTarget, OnMouseOut, mouseoutEvent) \ - macro(specificEventTarget, OnMouseOver, mouseoverEvent) \ - macro(specificEventTarget, OnMouseUp, mouseupEvent) \ - macro(specificEventTarget, OnMouseWheel, mousewheelEvent) \ - macro(specificEventTarget, OnBeforeCut, beforecutEvent) \ - macro(specificEventTarget, OnCut, cutEvent) \ - macro(specificEventTarget, OnBeforeCopy, beforecopyEvent) \ - macro(specificEventTarget, OnCopy, copyEvent) \ - macro(specificEventTarget, OnBeforePaste, beforepasteEvent) \ - macro(specificEventTarget, OnPaste, pasteEvent) \ - macro(specificEventTarget, OnDragEnter, dragenterEvent) \ - macro(specificEventTarget, OnDragOver, dragoverEvent) \ - macro(specificEventTarget, OnDragLeave, dragleaveEvent) \ - macro(specificEventTarget, OnDrop, dropEvent) \ - macro(specificEventTarget, OnDragStart, dragstartEvent) \ - macro(specificEventTarget, OnDrag, dragEvent) \ - macro(specificEventTarget, OnDragEnd, dragendEvent) \ - macro(specificEventTarget, OnReset, resetEvent) \ - macro(specificEventTarget, OnResize, resizeEvent) \ - macro(specificEventTarget, OnScroll, scrollEvent) \ - macro(specificEventTarget, OnSearch, searchEvent) \ - macro(specificEventTarget, OnSelect, selectEvent) \ - macro(specificEventTarget, OnSelectStart, selectstartEvent) \ - macro(specificEventTarget, OnSubmit, submitEvent) \ - macro(specificEventTarget, OnUnload, unloadEvent) \ -/* #if ENABLE(TOUCH_EVENTS) // Android */ \ - macro(specificEventTarget, OnTouchStart, touchstartEvent) \ - macro(specificEventTarget, OnTouchMove, touchmoveEvent) \ - macro(specificEventTarget, OnTouchEnd, touchendEvent) \ - macro(specificEventTarget, OnTouchCancel, touchcancelEvent) \ -/* #endif */ \ - -#define EVENT_LISTENER_GETTER(specificEventTarget, name, event) \ -JSC::JSValuePtr js##specificEventTarget##name(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot& slot) \ -{ \ - return static_cast<JS##specificEventTarget*>(slot.slotBase())->getListener(event); \ -} \ - -#define EVENT_LISTENER_SETTER(specificEventTarget, name, event) \ -void setJS##specificEventTarget##name(JSC::ExecState* exec, JSC::JSObject* baseObject, JSC::JSValuePtr value) \ -{ \ - static_cast<JS##specificEventTarget*>(baseObject)->setListener(exec, event, value); \ -} \ - -#define DECLARE_JS_EVENT_LISTENERS(specificEventTarget) \ - JS_EVENT_LISTENER_FOR_EACH_LISTENER(specificEventTarget, EVENT_LISTENER_GETTER) \ - JS_EVENT_LISTENER_FOR_EACH_LISTENER(specificEventTarget, EVENT_LISTENER_SETTER) \ - -#endif // JSEventTargetBase_h diff --git a/WebCore/bindings/js/JSGeolocationCustom.cpp b/WebCore/bindings/js/JSGeolocationCustom.cpp index c818dd9..493166c 100644 --- a/WebCore/bindings/js/JSGeolocationCustom.cpp +++ b/WebCore/bindings/js/JSGeolocationCustom.cpp @@ -39,28 +39,28 @@ using namespace JSC; namespace WebCore { -static PassRefPtr<PositionOptions> createPositionOptions(ExecState* exec, JSValuePtr value) +static PassRefPtr<PositionOptions> createPositionOptions(ExecState* exec, JSValue value) { if (!value.isObject()) return 0; JSObject* object = asObject(value); - JSValuePtr enableHighAccuracyValue = object->get(exec, Identifier(exec, "enableHighAccuracy")); + JSValue enableHighAccuracyValue = object->get(exec, Identifier(exec, "enableHighAccuracy")); if (exec->hadException()) return 0; bool enableHighAccuracy = enableHighAccuracyValue.toBoolean(exec); if (exec->hadException()) return 0; - JSValuePtr timeoutValue = object->get(exec, Identifier(exec, "timeout")); + JSValue timeoutValue = object->get(exec, Identifier(exec, "timeout")); if (exec->hadException()) return 0; unsigned timeout = timeoutValue.toUInt32(exec); if (exec->hadException()) return 0; - JSValuePtr maximumAgeValue = object->get(exec, Identifier(exec, "maximumAge")); + JSValue maximumAgeValue = object->get(exec, Identifier(exec, "maximumAge")); if (exec->hadException()) return 0; unsigned maximumAge = maximumAgeValue.toUInt32(exec); @@ -70,11 +70,11 @@ static PassRefPtr<PositionOptions> createPositionOptions(ExecState* exec, JSValu return PositionOptions::create(enableHighAccuracy, timeout, maximumAge); } -JSValuePtr JSGeolocation::getCurrentPosition(ExecState* exec, const ArgList& args) +JSValue JSGeolocation::getCurrentPosition(ExecState* exec, const ArgList& args) { // Arguments: PositionCallback, (optional)PositionErrorCallback, (optional)PositionOptions RefPtr<PositionCallback> positionCallback; - JSObject* object = args.at(exec, 0).getObject(); + JSObject* object = args.at(0).getObject(); if (exec->hadException()) return jsUndefined(); if (!object) { @@ -86,8 +86,8 @@ JSValuePtr JSGeolocation::getCurrentPosition(ExecState* exec, const ArgList& arg positionCallback = JSCustomPositionCallback::create(object, frame); RefPtr<PositionErrorCallback> positionErrorCallback; - if (!args.at(exec, 1).isUndefinedOrNull()) { - JSObject* object = args.at(exec, 1).getObject(); + if (!args.at(1).isUndefinedOrNull()) { + JSObject* object = args.at(1).getObject(); if (!object) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); @@ -98,22 +98,22 @@ JSValuePtr JSGeolocation::getCurrentPosition(ExecState* exec, const ArgList& arg } RefPtr<PositionOptions> positionOptions; - if (!args.at(exec, 2).isUndefinedOrNull()) { - positionOptions = createPositionOptions(exec, args.at(exec, 2)); + if (!args.at(2).isUndefinedOrNull()) { + positionOptions = createPositionOptions(exec, args.at(2)); if (exec->hadException()) return jsUndefined(); } - m_impl->getCurrentPosition(positionCallback.release(), positionErrorCallback.release(), positionOptions.get()); + m_impl->getCurrentPosition(positionCallback.release(), positionErrorCallback.release(), positionOptions.release()); return jsUndefined(); } -JSValuePtr JSGeolocation::watchPosition(ExecState* exec, const ArgList& args) +JSValue JSGeolocation::watchPosition(ExecState* exec, const ArgList& args) { // Arguments: PositionCallback, (optional)PositionErrorCallback, (optional)PositionOptions RefPtr<PositionCallback> positionCallback; - JSObject* object = args.at(exec, 0).getObject(); + JSObject* object = args.at(0).getObject(); if (exec->hadException()) return jsUndefined(); if (!object) { @@ -125,8 +125,8 @@ JSValuePtr JSGeolocation::watchPosition(ExecState* exec, const ArgList& args) positionCallback = JSCustomPositionCallback::create(object, frame); RefPtr<PositionErrorCallback> positionErrorCallback; - if (!args.at(exec, 1).isUndefinedOrNull()) { - JSObject* object = args.at(exec, 1).getObject(); + if (!args.at(1).isUndefinedOrNull()) { + JSObject* object = args.at(1).getObject(); if (!object) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); @@ -137,13 +137,13 @@ JSValuePtr JSGeolocation::watchPosition(ExecState* exec, const ArgList& args) } RefPtr<PositionOptions> positionOptions; - if (!args.at(exec, 2).isUndefinedOrNull()) { - positionOptions = createPositionOptions(exec, args.at(exec, 2)); + if (!args.at(2).isUndefinedOrNull()) { + positionOptions = createPositionOptions(exec, args.at(2)); if (exec->hadException()) return jsUndefined(); } - int watchID = m_impl->watchPosition(positionCallback.release(), positionErrorCallback.release(), positionOptions.get()); + int watchID = m_impl->watchPosition(positionCallback.release(), positionErrorCallback.release(), positionOptions.release()); return jsNumber(exec, watchID); } diff --git a/WebCore/bindings/js/JSHTMLAllCollection.h b/WebCore/bindings/js/JSHTMLAllCollection.h index 511c9d7..d559d3b 100644 --- a/WebCore/bindings/js/JSHTMLAllCollection.h +++ b/WebCore/bindings/js/JSHTMLAllCollection.h @@ -40,7 +40,7 @@ namespace WebCore { { } - static PassRefPtr<JSC::Structure> createStructure(JSC::JSValuePtr proto) + static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue proto) { return JSC::Structure::create(proto, JSC::TypeInfo(JSC::ObjectType, JSC::MasqueradesAsUndefined)); } diff --git a/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp b/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp index a99a36d..de6565d 100644 --- a/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp +++ b/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp @@ -38,7 +38,7 @@ bool JSHTMLAppletElement::customGetOwnPropertySlot(ExecState* exec, const Identi return runtimeObjectCustomGetOwnPropertySlot(exec, propertyName, slot, this); } -bool JSHTMLAppletElement::customPut(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot) +bool JSHTMLAppletElement::customPut(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { return runtimeObjectCustomPut(exec, propertyName, value, impl(), slot); } @@ -53,7 +53,7 @@ bool JSHTMLAppletElement::canGetItemsForName(ExecState*, HTMLAppletElement*, con return propertyName == "__apple_runtime_object"; } -JSValuePtr JSHTMLAppletElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSHTMLAppletElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { return runtimeObjectGetter(exec, propertyName, slot); } diff --git a/WebCore/bindings/js/JSHTMLCollectionCustom.cpp b/WebCore/bindings/js/JSHTMLCollectionCustom.cpp index e9f12bf..4100468 100644 --- a/WebCore/bindings/js/JSHTMLCollectionCustom.cpp +++ b/WebCore/bindings/js/JSHTMLCollectionCustom.cpp @@ -35,7 +35,7 @@ using namespace JSC; namespace WebCore { -static JSValuePtr getNamedItems(ExecState* exec, HTMLCollection* impl, const Identifier& propertyName) +static JSValue getNamedItems(ExecState* exec, HTMLCollection* impl, const Identifier& propertyName) { Vector<RefPtr<Node> > namedItems; impl->namedItems(propertyName, namedItems); @@ -51,7 +51,7 @@ static JSValuePtr getNamedItems(ExecState* exec, HTMLCollection* impl, const Ide // HTMLCollections are strange objects, they support both get and call, // so that document.forms.item(0) and document.forms(0) both work. -static JSValuePtr callHTMLCollection(ExecState* exec, JSObject* function, JSValuePtr, const ArgList& args) +static JSValue JSC_HOST_CALL callHTMLCollection(ExecState* exec, JSObject* function, JSValue, const ArgList& args) { if (args.size() < 1) return jsUndefined(); @@ -64,7 +64,7 @@ static JSValuePtr callHTMLCollection(ExecState* exec, JSObject* function, JSValu if (args.size() == 1) { // Support for document.all(<index>) etc. bool ok; - UString string = args.at(exec, 0).toString(exec); + UString string = args.at(0).toString(exec); unsigned index = string.toUInt32(&ok, false); if (ok) return toJS(exec, collection->item(index)); @@ -75,8 +75,8 @@ static JSValuePtr callHTMLCollection(ExecState* exec, JSObject* function, JSValu // The second arg, if set, is the index of the item we want bool ok; - UString string = args.at(exec, 0).toString(exec); - unsigned index = args.at(exec, 1).toString(exec).toUInt32(&ok, false); + UString string = args.at(0).toString(exec); + unsigned index = args.at(1).toString(exec).toUInt32(&ok, false); if (ok) { String pstr = string; Node* node = collection->namedItem(pstr); @@ -102,27 +102,27 @@ bool JSHTMLCollection::canGetItemsForName(ExecState* exec, HTMLCollection* thisO return !getNamedItems(exec, thisObj, propertyName).isUndefined(); } -JSValuePtr JSHTMLCollection::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSHTMLCollection::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { JSHTMLCollection* thisObj = static_cast<JSHTMLCollection*>(asObject(slot.slotBase())); return getNamedItems(exec, thisObj->impl(), propertyName); } -JSValuePtr JSHTMLCollection::item(ExecState* exec, const ArgList& args) +JSValue JSHTMLCollection::item(ExecState* exec, const ArgList& args) { bool ok; - uint32_t index = args.at(exec, 0).toString(exec).toUInt32(&ok, false); + uint32_t index = args.at(0).toString(exec).toUInt32(&ok, false); if (ok) return toJS(exec, impl()->item(index)); - return getNamedItems(exec, impl(), Identifier(exec, args.at(exec, 0).toString(exec))); + return getNamedItems(exec, impl(), Identifier(exec, args.at(0).toString(exec))); } -JSValuePtr JSHTMLCollection::namedItem(ExecState* exec, const ArgList& args) +JSValue JSHTMLCollection::namedItem(ExecState* exec, const ArgList& args) { - return getNamedItems(exec, impl(), Identifier(exec, args.at(exec, 0).toString(exec))); + return getNamedItems(exec, impl(), Identifier(exec, args.at(0).toString(exec))); } -JSValuePtr toJS(ExecState* exec, HTMLCollection* collection) +JSValue toJS(ExecState* exec, HTMLCollection* collection) { if (!collection) return jsNull(); @@ -133,10 +133,10 @@ JSValuePtr toJS(ExecState* exec, HTMLCollection* collection) return wrapper; switch (collection->type()) { - case HTMLCollection::SelectOptions: + case SelectOptions: wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, HTMLOptionsCollection, collection); break; - case HTMLCollection::DocAll: + case DocAll: typedef HTMLCollection HTMLAllCollection; wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, HTMLAllCollection, collection); break; diff --git a/WebCore/bindings/js/JSHTMLDocumentCustom.cpp b/WebCore/bindings/js/JSHTMLDocumentCustom.cpp index 1bc40ff..c113ec7 100644 --- a/WebCore/bindings/js/JSHTMLDocumentCustom.cpp +++ b/WebCore/bindings/js/JSHTMLDocumentCustom.cpp @@ -54,7 +54,7 @@ bool JSHTMLDocument::canGetItemsForName(ExecState*, HTMLDocument* document, cons return atomicPropertyName && (document->hasNamedItem(atomicPropertyName) || document->hasExtraNamedItem(atomicPropertyName)); } -JSValuePtr JSHTMLDocument::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSHTMLDocument::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { JSHTMLDocument* thisObj = static_cast<JSHTMLDocument*>(asObject(slot.slotBase())); HTMLDocument* document = static_cast<HTMLDocument*>(thisObj->impl()); @@ -81,17 +81,17 @@ JSValuePtr JSHTMLDocument::nameGetter(ExecState* exec, const Identifier& propert // Custom attributes -JSValuePtr JSHTMLDocument::all(ExecState* exec) const +JSValue JSHTMLDocument::all(ExecState* exec) const { // If "all" has been overwritten, return the overwritten value - JSValuePtr v = getDirect(Identifier(exec, "all")); + JSValue v = getDirect(Identifier(exec, "all")); if (v) return v; return toJS(exec, static_cast<HTMLDocument*>(impl())->all().get()); } -void JSHTMLDocument::setAll(ExecState* exec, JSValuePtr value) +void JSHTMLDocument::setAll(ExecState* exec, JSValue value) { // Add "all" to the property map. putDirect(Identifier(exec, "all"), value); @@ -99,7 +99,7 @@ void JSHTMLDocument::setAll(ExecState* exec, JSValuePtr value) // Custom functions -JSValuePtr JSHTMLDocument::open(ExecState* exec, const ArgList& args) +JSValue JSHTMLDocument::open(ExecState* exec, const ArgList& args) { // For compatibility with other browsers, pass open calls with more than 2 parameters to the window. if (args.size() > 2) { @@ -107,7 +107,7 @@ JSValuePtr JSHTMLDocument::open(ExecState* exec, const ArgList& args) if (frame) { JSDOMWindowShell* wrapper = toJSDOMWindowShell(frame); if (wrapper) { - JSValuePtr function = wrapper->get(exec, Identifier(exec, "open")); + JSValue function = wrapper->get(exec, Identifier(exec, "open")); CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) @@ -135,14 +135,14 @@ static inline void documentWrite(ExecState* exec, const ArgList& args, HTMLDocum size_t size = args.size(); - UString firstString = args.at(exec, 0).toString(exec); + UString firstString = args.at(0).toString(exec); SegmentedString segmentedString = String(firstString); if (size != 1) { if (!size) segmentedString.clear(); else { for (size_t i = 1; i < size; ++i) { - UString subsequentString = args.at(exec, i).toString(exec); + UString subsequentString = args.at(i).toString(exec); segmentedString.append(SegmentedString(String(subsequentString))); } } @@ -154,13 +154,13 @@ static inline void documentWrite(ExecState* exec, const ArgList& args, HTMLDocum document->write(segmentedString, activeDocument); } -JSValuePtr JSHTMLDocument::write(ExecState* exec, const ArgList& args) +JSValue JSHTMLDocument::write(ExecState* exec, const ArgList& args) { documentWrite(exec, args, static_cast<HTMLDocument*>(impl()), DoNotAddNewline); return jsUndefined(); } -JSValuePtr JSHTMLDocument::writeln(ExecState* exec, const ArgList& args) +JSValue JSHTMLDocument::writeln(ExecState* exec, const ArgList& args) { documentWrite(exec, args, static_cast<HTMLDocument*>(impl()), DoAddNewline); return jsUndefined(); diff --git a/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp b/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp index 2856393..19aae86 100644 --- a/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp +++ b/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp @@ -38,7 +38,7 @@ bool JSHTMLEmbedElement::customGetOwnPropertySlot(ExecState* exec, const Identif return runtimeObjectCustomGetOwnPropertySlot(exec, propertyName, slot, this); } -bool JSHTMLEmbedElement::customPut(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot) +bool JSHTMLEmbedElement::customPut(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { return runtimeObjectCustomPut(exec, propertyName, value, impl(), slot); } @@ -53,7 +53,7 @@ bool JSHTMLEmbedElement::canGetItemsForName(ExecState*, HTMLEmbedElement*, const return propertyName == "__apple_runtime_object"; } -JSValuePtr JSHTMLEmbedElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSHTMLEmbedElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { return runtimeObjectGetter(exec, propertyName, slot); } diff --git a/WebCore/bindings/js/JSHTMLFormElementCustom.cpp b/WebCore/bindings/js/JSHTMLFormElementCustom.cpp index 68b727b..8bf543c 100644 --- a/WebCore/bindings/js/JSHTMLFormElementCustom.cpp +++ b/WebCore/bindings/js/JSHTMLFormElementCustom.cpp @@ -43,7 +43,7 @@ bool JSHTMLFormElement::canGetItemsForName(ExecState*, HTMLFormElement* form, co return namedItems.size(); } -JSValuePtr JSHTMLFormElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSHTMLFormElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { HTMLFormElement* form = static_cast<HTMLFormElement*>(static_cast<JSHTMLElement*>(asObject(slot.slotBase()))->impl()); @@ -57,7 +57,7 @@ JSValuePtr JSHTMLFormElement::nameGetter(ExecState* exec, const Identifier& prop return jsUndefined(); } -JSValuePtr JSHTMLFormElement::submit(ExecState* exec, const ArgList&) +JSValue JSHTMLFormElement::submit(ExecState* exec, const ArgList&) { Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); if (!activeFrame) diff --git a/WebCore/bindings/js/JSHTMLFrameElementCustom.cpp b/WebCore/bindings/js/JSHTMLFrameElementCustom.cpp index a97a72a..0a5d1f1 100644 --- a/WebCore/bindings/js/JSHTMLFrameElementCustom.cpp +++ b/WebCore/bindings/js/JSHTMLFrameElementCustom.cpp @@ -40,14 +40,14 @@ namespace WebCore { static inline bool allowSettingJavascriptURL(ExecState* exec, HTMLFrameElement* imp, const String& value) { - if (protocolIs(parseURL(value), "javascript")) { + if (protocolIsJavaScript(parseURL(value))) { if (!checkNodeSecurity(exec, imp->contentDocument())) return false; } return true; } -void JSHTMLFrameElement::setSrc(ExecState* exec, JSValuePtr value) +void JSHTMLFrameElement::setSrc(ExecState* exec, JSValue value) { HTMLFrameElement* imp = static_cast<HTMLFrameElement*>(impl()); String srcValue = valueToStringWithNullCheck(exec, value); @@ -59,7 +59,7 @@ void JSHTMLFrameElement::setSrc(ExecState* exec, JSValuePtr value) return; } -void JSHTMLFrameElement::setLocation(ExecState* exec, JSValuePtr value) +void JSHTMLFrameElement::setLocation(ExecState* exec, JSValue value) { HTMLFrameElement* imp = static_cast<HTMLFrameElement*>(impl()); String locationValue = valueToStringWithNullCheck(exec, value); diff --git a/WebCore/bindings/js/JSHTMLFrameSetElementCustom.cpp b/WebCore/bindings/js/JSHTMLFrameSetElementCustom.cpp index f17cb89..05972e6 100644 --- a/WebCore/bindings/js/JSHTMLFrameSetElementCustom.cpp +++ b/WebCore/bindings/js/JSHTMLFrameSetElementCustom.cpp @@ -27,6 +27,7 @@ #include "JSHTMLFrameSetElement.h" #include "Document.h" +#include "HTMLCollection.h" #include "HTMLFrameElement.h" #include "HTMLFrameSetElement.h" #include "HTMLNames.h" @@ -46,7 +47,7 @@ bool JSHTMLFrameSetElement::canGetItemsForName(ExecState*, HTMLFrameSetElement* return frame && frame->hasTagName(frameTag); } -JSValuePtr JSHTMLFrameSetElement::nameGetter(ExecState*, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSHTMLFrameSetElement::nameGetter(ExecState*, const Identifier& propertyName, const PropertySlot& slot) { JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(asObject(slot.slotBase())); HTMLElement* element = static_cast<HTMLElement*>(thisObj->impl()); diff --git a/WebCore/bindings/js/JSHTMLIFrameElementCustom.cpp b/WebCore/bindings/js/JSHTMLIFrameElementCustom.cpp index 1a0fc1c..afff977 100644 --- a/WebCore/bindings/js/JSHTMLIFrameElementCustom.cpp +++ b/WebCore/bindings/js/JSHTMLIFrameElementCustom.cpp @@ -38,13 +38,13 @@ using namespace JSC; namespace WebCore { -void JSHTMLIFrameElement::setSrc(ExecState* exec, JSValuePtr value) +void JSHTMLIFrameElement::setSrc(ExecState* exec, JSValue value) { HTMLIFrameElement* imp = static_cast<HTMLIFrameElement*>(impl()); String srcValue = valueToStringWithNullCheck(exec, value); - if (protocolIs(parseURL(srcValue), "javascript")) { + if (protocolIsJavaScript(parseURL(srcValue))) { if (!checkNodeSecurity(exec, imp->contentDocument())) return; } diff --git a/WebCore/bindings/js/JSHTMLInputElementCustom.cpp b/WebCore/bindings/js/JSHTMLInputElementCustom.cpp index aa52007..6b47622 100644 --- a/WebCore/bindings/js/JSHTMLInputElementCustom.cpp +++ b/WebCore/bindings/js/JSHTMLInputElementCustom.cpp @@ -26,13 +26,47 @@ #include "config.h" #include "JSHTMLInputElement.h" +#include "Document.h" #include "HTMLInputElement.h" +#include "Settings.h" using namespace JSC; namespace WebCore { -JSValuePtr JSHTMLInputElement::selectionStart(ExecState* exec) const +static bool needsGmailQuirk(HTMLInputElement* input) +{ + Document* document = input->document(); + + const KURL& url = document->url(); + if (url.host() != "mail.google.com") + 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 = document->settings(); + if (!settings) + return false; + if (!settings->needsSiteSpecificQuirks()) + return false; + + return true; +} + +JSValue JSHTMLInputElement::type(ExecState* exec) const +{ + HTMLInputElement* input = static_cast<HTMLInputElement*>(impl()); + const AtomicString& type = input->type(); + + DEFINE_STATIC_LOCAL(const AtomicString, url, ("url")); + DEFINE_STATIC_LOCAL(const AtomicString, text, ("text")); + + if (type == url && needsGmailQuirk(input)) + return jsString(exec, text); + return jsString(exec, type); +} + +JSValue JSHTMLInputElement::selectionStart(ExecState* exec) const { HTMLInputElement* input = static_cast<HTMLInputElement*>(impl()); if (!input->canHaveSelection()) @@ -41,7 +75,7 @@ JSValuePtr JSHTMLInputElement::selectionStart(ExecState* exec) const return jsNumber(exec, input->selectionStart()); } -void JSHTMLInputElement::setSelectionStart(ExecState* exec, JSValuePtr value) +void JSHTMLInputElement::setSelectionStart(ExecState* exec, JSValue value) { HTMLInputElement* input = static_cast<HTMLInputElement*>(impl()); if (!input->canHaveSelection()) @@ -50,7 +84,7 @@ void JSHTMLInputElement::setSelectionStart(ExecState* exec, JSValuePtr value) input->setSelectionStart(value.toInt32(exec)); } -JSValuePtr JSHTMLInputElement::selectionEnd(ExecState* exec) const +JSValue JSHTMLInputElement::selectionEnd(ExecState* exec) const { HTMLInputElement* input = static_cast<HTMLInputElement*>(impl()); if (!input->canHaveSelection()) @@ -59,7 +93,7 @@ JSValuePtr JSHTMLInputElement::selectionEnd(ExecState* exec) const return jsNumber(exec, input->selectionEnd()); } -void JSHTMLInputElement::setSelectionEnd(ExecState* exec, JSValuePtr value) +void JSHTMLInputElement::setSelectionEnd(ExecState* exec, JSValue value) { HTMLInputElement* input = static_cast<HTMLInputElement*>(impl()); if (!input->canHaveSelection()) @@ -68,14 +102,14 @@ void JSHTMLInputElement::setSelectionEnd(ExecState* exec, JSValuePtr value) input->setSelectionEnd(value.toInt32(exec)); } -JSValuePtr JSHTMLInputElement::setSelectionRange(ExecState* exec, const ArgList& args) +JSValue JSHTMLInputElement::setSelectionRange(ExecState* exec, const ArgList& args) { HTMLInputElement* input = static_cast<HTMLInputElement*>(impl()); if (!input->canHaveSelection()) return throwError(exec, TypeError); - int start = args.at(exec, 0).toInt32(exec); - int end = args.at(exec, 1).toInt32(exec); + int start = args.at(0).toInt32(exec); + int end = args.at(1).toInt32(exec); input->setSelectionRange(start, end); return jsUndefined(); diff --git a/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp b/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp index 5ad3454..f7f12b9 100644 --- a/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp +++ b/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp @@ -38,7 +38,7 @@ bool JSHTMLObjectElement::customGetOwnPropertySlot(ExecState* exec, const Identi return runtimeObjectCustomGetOwnPropertySlot(exec, propertyName, slot, this); } -bool JSHTMLObjectElement::customPut(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot) +bool JSHTMLObjectElement::customPut(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { return runtimeObjectCustomPut(exec, propertyName, value, impl(), slot); } @@ -53,7 +53,7 @@ bool JSHTMLObjectElement::canGetItemsForName(ExecState*, HTMLObjectElement*, con return propertyName == "__apple_runtime_object"; } -JSValuePtr JSHTMLObjectElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSHTMLObjectElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { return runtimeObjectGetter(exec, propertyName, slot); } diff --git a/WebCore/bindings/js/JSHTMLOptionsCollectionCustom.cpp b/WebCore/bindings/js/JSHTMLOptionsCollectionCustom.cpp index b6e53de..460ba08 100644 --- a/WebCore/bindings/js/JSHTMLOptionsCollectionCustom.cpp +++ b/WebCore/bindings/js/JSHTMLOptionsCollectionCustom.cpp @@ -35,13 +35,13 @@ using namespace JSC; namespace WebCore { -JSValuePtr JSHTMLOptionsCollection::length(ExecState* exec) const +JSValue JSHTMLOptionsCollection::length(ExecState* exec) const { HTMLOptionsCollection* imp = static_cast<HTMLOptionsCollection*>(impl()); return jsNumber(exec, imp->length()); } -void JSHTMLOptionsCollection::setLength(ExecState* exec, JSValuePtr value) +void JSHTMLOptionsCollection::setLength(ExecState* exec, JSValue value) { HTMLOptionsCollection* imp = static_cast<HTMLOptionsCollection*>(impl()); ExceptionCode ec = 0; @@ -60,23 +60,23 @@ void JSHTMLOptionsCollection::setLength(ExecState* exec, JSValuePtr value) setDOMException(exec, ec); } -void JSHTMLOptionsCollection::indexSetter(ExecState* exec, unsigned index, JSValuePtr value) +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); } -JSValuePtr JSHTMLOptionsCollection::add(ExecState* exec, const ArgList& args) +JSValue JSHTMLOptionsCollection::add(ExecState* exec, const ArgList& args) { HTMLOptionsCollection* imp = static_cast<HTMLOptionsCollection*>(impl()); - HTMLOptionElement* option = toHTMLOptionElement(args.at(exec, 0)); + HTMLOptionElement* option = toHTMLOptionElement(args.at(0)); ExceptionCode ec = 0; if (args.size() < 2) imp->add(option, ec); else { bool ok; - int index = args.at(exec, 1).toInt32(exec, ok); + int index = args.at(1).toInt32(exec, ok); if (exec->hadException()) return jsUndefined(); if (!ok) @@ -88,7 +88,7 @@ JSValuePtr JSHTMLOptionsCollection::add(ExecState* exec, const ArgList& args) return jsUndefined(); } -JSValuePtr JSHTMLOptionsCollection::remove(ExecState* exec, const ArgList& args) +JSValue JSHTMLOptionsCollection::remove(ExecState* exec, const ArgList& args) { HTMLOptionsCollection* imp = static_cast<HTMLOptionsCollection*>(impl()); JSHTMLSelectElement* base = static_cast<JSHTMLSelectElement*>(asObject(toJS(exec, imp->base()))); diff --git a/WebCore/bindings/js/JSHTMLSelectElementCustom.cpp b/WebCore/bindings/js/JSHTMLSelectElementCustom.cpp index 755aec5..9bb6b75 100644 --- a/WebCore/bindings/js/JSHTMLSelectElementCustom.cpp +++ b/WebCore/bindings/js/JSHTMLSelectElementCustom.cpp @@ -32,21 +32,21 @@ namespace WebCore { using namespace JSC; using namespace HTMLNames; -JSValuePtr JSHTMLSelectElement::remove(ExecState* exec, const ArgList& args) +JSValue JSHTMLSelectElement::remove(ExecState* exec, const ArgList& args) { HTMLSelectElement& select = *static_cast<HTMLSelectElement*>(impl()); // we support both options index and options objects - HTMLElement* element = toHTMLElement(args.at(exec, 0)); + HTMLElement* element = toHTMLElement(args.at(0)); if (element && element->hasTagName(optionTag)) select.remove(static_cast<HTMLOptionElement*>(element)->index()); else - select.remove(args.at(exec, 0).toInt32(exec)); + select.remove(args.at(0).toInt32(exec)); return jsUndefined(); } -void selectIndexSetter(HTMLSelectElement* select, JSC::ExecState* exec, unsigned index, JSC::JSValuePtr value) +void selectIndexSetter(HTMLSelectElement* select, JSC::ExecState* exec, unsigned index, JSC::JSValue value) { if (value.isUndefinedOrNull()) select->remove(index); @@ -61,7 +61,7 @@ void selectIndexSetter(HTMLSelectElement* select, JSC::ExecState* exec, unsigned } } -void JSHTMLSelectElement::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValuePtr value) +void JSHTMLSelectElement::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) { selectIndexSetter(static_cast<HTMLSelectElement*>(impl()), exec, index, value); } diff --git a/WebCore/bindings/js/JSHTMLSelectElementCustom.h b/WebCore/bindings/js/JSHTMLSelectElementCustom.h index 87344b5..a449038 100644 --- a/WebCore/bindings/js/JSHTMLSelectElementCustom.h +++ b/WebCore/bindings/js/JSHTMLSelectElementCustom.h @@ -33,7 +33,7 @@ namespace WebCore { -void selectIndexSetter(HTMLSelectElement*, JSC::ExecState*, unsigned index, JSC::JSValuePtr); +void selectIndexSetter(HTMLSelectElement*, JSC::ExecState*, unsigned index, JSC::JSValue); } diff --git a/WebCore/bindings/js/JSHistoryCustom.cpp b/WebCore/bindings/js/JSHistoryCustom.cpp index e83ac40..998a364 100644 --- a/WebCore/bindings/js/JSHistoryCustom.cpp +++ b/WebCore/bindings/js/JSHistoryCustom.cpp @@ -37,17 +37,17 @@ using namespace JSC; namespace WebCore { -static JSValuePtr nonCachingStaticBackFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) +static JSValue nonCachingStaticBackFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) { return new (exec) PrototypeFunction(exec, 0, propertyName, jsHistoryPrototypeFunctionBack); } -static JSValuePtr nonCachingStaticForwardFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) +static JSValue nonCachingStaticForwardFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) { return new (exec) PrototypeFunction(exec, 0, propertyName, jsHistoryPrototypeFunctionForward); } -static JSValuePtr nonCachingStaticGoFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) +static JSValue nonCachingStaticGoFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) { return new (exec) PrototypeFunction(exec, 1, propertyName, jsHistoryPrototypeFunctionGo); } @@ -92,7 +92,7 @@ bool JSHistory::customGetOwnPropertySlot(ExecState* exec, const Identifier& prop return true; } -bool JSHistory::customPut(ExecState* exec, const Identifier&, JSValuePtr, PutPropertySlot&) +bool JSHistory::customPut(ExecState* exec, const Identifier&, JSValue, PutPropertySlot&) { // Only allow putting by frames in the same origin. if (!allowsAccessFromFrame(exec, impl()->frame())) diff --git a/WebCore/bindings/js/JSImageConstructor.cpp b/WebCore/bindings/js/JSImageConstructor.cpp index aa44c73..4a27bb4 100644 --- a/WebCore/bindings/js/JSImageConstructor.cpp +++ b/WebCore/bindings/js/JSImageConstructor.cpp @@ -34,13 +34,14 @@ ASSERT_CLASS_FITS_IN_CELL(JSImageConstructor); const ClassInfo JSImageConstructor::s_info = { "ImageConstructor", 0, 0, 0 }; -JSImageConstructor::JSImageConstructor(ExecState* exec, ScriptExecutionContext* context) +JSImageConstructor::JSImageConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) : DOMObject(JSImageConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) - , m_globalObject(toJSDOMGlobalObject(context)) + , m_globalObject(globalObject) { - ASSERT(context->isDocument()); + ASSERT(globalObject->scriptExecutionContext()); + ASSERT(globalObject->scriptExecutionContext()->isDocument()); - putDirect(exec->propertyNames().prototype, JSHTMLImageElementPrototype::self(exec), None); + putDirect(exec->propertyNames().prototype, JSHTMLImageElementPrototype::self(exec, exec->lexicalGlobalObject()), None); } Document* JSImageConstructor::document() const @@ -56,14 +57,16 @@ static JSObject* constructImage(ExecState* exec, JSObject* constructor, const Ar int height = 0; if (args.size() > 0) { widthSet = true; - width = args.at(exec, 0).toInt32(exec); + width = args.at(0).toInt32(exec); } if (args.size() > 1) { heightSet = true; - height = args.at(exec, 1).toInt32(exec); + height = args.at(1).toInt32(exec); } Document* document = static_cast<JSImageConstructor*>(constructor)->document(); + if (!document) + return throwError(exec, ReferenceError, "Image constructor associated document is unavailable"); // 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 diff --git a/WebCore/bindings/js/JSImageConstructor.h b/WebCore/bindings/js/JSImageConstructor.h index 578d1cf..8dc7add 100644 --- a/WebCore/bindings/js/JSImageConstructor.h +++ b/WebCore/bindings/js/JSImageConstructor.h @@ -27,7 +27,7 @@ namespace WebCore { class JSImageConstructor : public DOMObject { public: - JSImageConstructor(JSC::ExecState*, ScriptExecutionContext*); + JSImageConstructor(JSC::ExecState*, JSDOMGlobalObject*); Document* document() const; static const JSC::ClassInfo s_info; diff --git a/WebCore/bindings/js/JSImageDataCustom.cpp b/WebCore/bindings/js/JSImageDataCustom.cpp index 06c5d1b..32fe58b 100644 --- a/WebCore/bindings/js/JSImageDataCustom.cpp +++ b/WebCore/bindings/js/JSImageDataCustom.cpp @@ -36,7 +36,7 @@ using namespace JSC; namespace WebCore { -JSValuePtr toJS(ExecState* exec, ImageData* imageData) +JSValue toJS(ExecState* exec, ImageData* imageData) { if (!imageData) return jsNull(); diff --git a/WebCore/bindings/js/JSInspectedObjectWrapper.cpp b/WebCore/bindings/js/JSInspectedObjectWrapper.cpp index 09007c1..fff7aee 100644 --- a/WebCore/bindings/js/JSInspectedObjectWrapper.cpp +++ b/WebCore/bindings/js/JSInspectedObjectWrapper.cpp @@ -47,7 +47,7 @@ static GlobalObjectWrapperMap& wrappers() const ClassInfo JSInspectedObjectWrapper::s_info = { "JSInspectedObjectWrapper", &JSQuarantinedObjectWrapper::s_info, 0, 0 }; -JSValuePtr JSInspectedObjectWrapper::wrap(ExecState* unwrappedExec, JSValuePtr unwrappedValue) +JSValue JSInspectedObjectWrapper::wrap(ExecState* unwrappedExec, JSValue unwrappedValue) { if (!unwrappedValue.isObject()) return unwrappedValue; @@ -61,7 +61,7 @@ JSValuePtr JSInspectedObjectWrapper::wrap(ExecState* unwrappedExec, JSValuePtr u if (JSInspectedObjectWrapper* wrapper = wrapperMap->get(unwrappedObject)) return wrapper; - JSValuePtr prototype = unwrappedObject->prototype(); + JSValue prototype = unwrappedObject->prototype(); ASSERT(prototype.isNull() || prototype.isObject()); if (prototype.isNull()) @@ -96,7 +96,7 @@ JSInspectedObjectWrapper::~JSInspectedObjectWrapper() } } -JSValuePtr JSInspectedObjectWrapper::prepareIncomingValue(ExecState*, JSValuePtr value) const +JSValue JSInspectedObjectWrapper::prepareIncomingValue(ExecState*, JSValue value) const { // The Inspector is only allowed to pass primitive values and wrapped objects to objects from the inspected page. diff --git a/WebCore/bindings/js/JSInspectedObjectWrapper.h b/WebCore/bindings/js/JSInspectedObjectWrapper.h index 273c0b0..201feb6 100644 --- a/WebCore/bindings/js/JSInspectedObjectWrapper.h +++ b/WebCore/bindings/js/JSInspectedObjectWrapper.h @@ -32,7 +32,7 @@ namespace WebCore { class JSInspectedObjectWrapper : public JSQuarantinedObjectWrapper { public: - static JSC::JSValuePtr wrap(JSC::ExecState* unwrappedExec, JSC::JSValuePtr unwrappedValue); + static JSC::JSValue wrap(JSC::ExecState* unwrappedExec, JSC::JSValue unwrappedValue); virtual ~JSInspectedObjectWrapper(); static const JSC::ClassInfo s_info; @@ -48,8 +48,8 @@ namespace WebCore { virtual bool allowsCallAsFunction() const { return true; } virtual bool allowsGetPropertyNames() const { return true; } - virtual JSC::JSValuePtr prepareIncomingValue(JSC::ExecState* unwrappedExec, JSC::JSValuePtr unwrappedValue) const; - virtual JSC::JSValuePtr wrapOutgoingValue(JSC::ExecState* unwrappedExec, JSC::JSValuePtr unwrappedValue) const { return wrap(unwrappedExec, unwrappedValue); } + virtual JSC::JSValue prepareIncomingValue(JSC::ExecState* unwrappedExec, JSC::JSValue unwrappedValue) const; + virtual JSC::JSValue wrapOutgoingValue(JSC::ExecState* unwrappedExec, JSC::JSValue unwrappedValue) const { return wrap(unwrappedExec, unwrappedValue); } virtual const JSC::ClassInfo* classInfo() const { return &s_info; } }; diff --git a/WebCore/bindings/js/JSInspectorCallbackWrapper.cpp b/WebCore/bindings/js/JSInspectorCallbackWrapper.cpp index 1fb5eae..0e14109 100644 --- a/WebCore/bindings/js/JSInspectorCallbackWrapper.cpp +++ b/WebCore/bindings/js/JSInspectorCallbackWrapper.cpp @@ -53,7 +53,7 @@ static Structure* leakInspectorCallbackWrapperStructure() return structure; } -JSValuePtr JSInspectorCallbackWrapper::wrap(ExecState* unwrappedExec, JSValuePtr unwrappedValue) +JSValue JSInspectorCallbackWrapper::wrap(ExecState* unwrappedExec, JSValue unwrappedValue) { if (!unwrappedValue.isObject()) return unwrappedValue; @@ -66,7 +66,7 @@ JSValuePtr JSInspectorCallbackWrapper::wrap(ExecState* unwrappedExec, JSValuePtr if (JSInspectorCallbackWrapper* wrapper = wrappers().get(unwrappedObject)) return wrapper; - JSValuePtr prototype = unwrappedObject->prototype(); + JSValue prototype = unwrappedObject->prototype(); ASSERT(prototype.isNull() || prototype.isObject()); if (prototype.isNull()) { @@ -88,7 +88,7 @@ JSInspectorCallbackWrapper::~JSInspectorCallbackWrapper() wrappers().remove(unwrappedObject()); } -JSValuePtr JSInspectorCallbackWrapper::prepareIncomingValue(ExecState* unwrappedExec, JSValuePtr unwrappedValue) const +JSValue JSInspectorCallbackWrapper::prepareIncomingValue(ExecState* unwrappedExec, JSValue unwrappedValue) const { if (JSQuarantinedObjectWrapper* wrapper = asWrapper(unwrappedValue)) { // The only time a wrapper should be passed into a JSInspectorCallbackWrapper is when a client-side storage callback diff --git a/WebCore/bindings/js/JSInspectorCallbackWrapper.h b/WebCore/bindings/js/JSInspectorCallbackWrapper.h index 49157c0..cfc2fb6 100644 --- a/WebCore/bindings/js/JSInspectorCallbackWrapper.h +++ b/WebCore/bindings/js/JSInspectorCallbackWrapper.h @@ -32,7 +32,7 @@ namespace WebCore { class JSInspectorCallbackWrapper : public JSQuarantinedObjectWrapper { public: - static JSC::JSValuePtr wrap(JSC::ExecState* unwrappedExec, JSC::JSValuePtr unwrappedValue); + static JSC::JSValue wrap(JSC::ExecState* unwrappedExec, JSC::JSValue unwrappedValue); virtual ~JSInspectorCallbackWrapper(); @@ -44,8 +44,8 @@ namespace WebCore { virtual bool allowsCallAsFunction() const { return true; } - virtual JSC::JSValuePtr prepareIncomingValue(JSC::ExecState* unwrappedExec, JSC::JSValuePtr unwrappedValue) const; - virtual JSC::JSValuePtr wrapOutgoingValue(JSC::ExecState* unwrappedExec, JSC::JSValuePtr unwrappedValue) const { return wrap(unwrappedExec, unwrappedValue); } + virtual JSC::JSValue prepareIncomingValue(JSC::ExecState* unwrappedExec, JSC::JSValue unwrappedValue) const; + virtual JSC::JSValue wrapOutgoingValue(JSC::ExecState* unwrappedExec, JSC::JSValue unwrappedValue) const { return wrap(unwrappedExec, unwrappedValue); } }; } // namespace WebCore diff --git a/WebCore/bindings/js/JSInspectorControllerCustom.cpp b/WebCore/bindings/js/JSInspectorControllerCustom.cpp index 79c69c8..b06c9e9 100644 --- a/WebCore/bindings/js/JSInspectorControllerCustom.cpp +++ b/WebCore/bindings/js/JSInspectorControllerCustom.cpp @@ -43,7 +43,6 @@ #include "FrameLoader.h" #include "InspectorController.h" #include "InspectorResource.h" -#include "JavaScriptProfile.h" #include "JSDOMWindow.h" #include "JSInspectedObjectWrapper.h" #include "JSInspectorCallbackWrapper.h" @@ -53,8 +52,6 @@ #include "Page.h" #include "TextIterator.h" #include "VisiblePosition.h" -#include <profiler/Profile.h> -#include <profiler/Profiler.h> #include <runtime/JSArray.h> #include <runtime/JSLock.h> #include <wtf/Vector.h> @@ -62,31 +59,22 @@ #if ENABLE(JAVASCRIPT_DEBUGGER) #include "JavaScriptCallFrame.h" #include "JavaScriptDebugServer.h" +#include "JavaScriptProfile.h" #include "JSJavaScriptCallFrame.h" +#include <profiler/Profile.h> +#include <profiler/Profiler.h> #endif using namespace JSC; namespace WebCore { -JSValuePtr JSInspectorController::profiles(JSC::ExecState* exec, const JSC::ArgList&) -{ - JSLock lock(false); - ArgList result; - const Vector<RefPtr<Profile> >& profiles = impl()->profiles(); - - for (size_t i = 0; i < profiles.size(); ++i) - result.append(toJS(exec, profiles[i].get())); - - return constructArray(exec, result); -} - -JSValuePtr JSInspectorController::highlightDOMNode(JSC::ExecState* exec, const JSC::ArgList& args) +JSValue JSInspectorController::highlightDOMNode(JSC::ExecState*, const JSC::ArgList& args) { if (args.size() < 1) return jsUndefined(); - JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(args.at(exec, 0)); + JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(args.at(0)); if (!wrapper) return jsUndefined(); @@ -99,51 +87,13 @@ JSValuePtr JSInspectorController::highlightDOMNode(JSC::ExecState* exec, const J return jsUndefined(); } -JSValuePtr JSInspectorController::addResourceSourceToFrame(ExecState* exec, const ArgList& args) -{ - if (args.size() < 2) - return jsUndefined(); - - bool ok = false; - unsigned identifier = args.at(exec, 0).toUInt32(exec, ok); - if (!ok) - return jsUndefined(); - - RefPtr<InspectorResource> resource = impl()->resources().get(identifier); - ASSERT(resource); - if (!resource) - return jsUndefined(); - - String sourceString = resource->sourceString(); - if (sourceString.isEmpty()) - return jsUndefined(); - - return jsBoolean(impl()->addSourceToFrame(resource->mimeType, sourceString, toNode(args.at(exec, 1)))); -} - -JSValuePtr JSInspectorController::addSourceToFrame(ExecState* exec, const ArgList& args) -{ - if (args.size() < 3) - return jsUndefined(); - - String mimeType = args.at(exec, 0).toString(exec); - if (exec->hadException()) - return jsUndefined(); - - String sourceString = args.at(exec, 1).toString(exec); - if (exec->hadException()) - return jsUndefined(); - - return jsBoolean(impl()->addSourceToFrame(mimeType, sourceString, toNode(args.at(exec, 1)))); -} - -JSValuePtr JSInspectorController::getResourceDocumentNode(ExecState* exec, const ArgList& args) +JSValue JSInspectorController::getResourceDocumentNode(ExecState* exec, const ArgList& args) { if (args.size() < 1) return jsUndefined(); bool ok = false; - unsigned identifier = args.at(exec, 0).toUInt32(exec, ok); + unsigned identifier = args.at(0).toUInt32(exec, ok); if (!ok) return jsUndefined(); @@ -152,33 +102,32 @@ JSValuePtr JSInspectorController::getResourceDocumentNode(ExecState* exec, const if (!resource) return jsUndefined(); - Frame* frame = resource->frame.get(); + Frame* frame = resource->frame(); Document* document = frame->document(); if (document->isPluginDocument() || document->isImageDocument() || document->isMediaDocument()) return jsUndefined(); - // FIXME: I am not sure if this is actually needed. Can we just use exec? - ExecState* resourceExec = toJSDOMWindowShell(resource->frame.get())->window()->globalExec(); + ExecState* resourceExec = toJSDOMWindowShell(frame)->window()->globalExec(); JSLock lock(false); return JSInspectedObjectWrapper::wrap(resourceExec, toJS(resourceExec, document)); } -JSValuePtr JSInspectorController::search(ExecState* exec, const ArgList& args) +JSValue JSInspectorController::search(ExecState* exec, const ArgList& args) { if (args.size() < 2) return jsUndefined(); - Node* node = toNode(args.at(exec, 0)); + Node* node = toNode(args.at(0)); if (!node) return jsUndefined(); - String target = args.at(exec, 1).toString(exec); + String target = args.at(1).toString(exec); if (exec->hadException()) return jsUndefined(); - ArgList result; + MarkedArgumentBuffer result; RefPtr<Range> searchRange(rangeOfContents(node)); ExceptionCode ec = 0; @@ -202,12 +151,12 @@ JSValuePtr JSInspectorController::search(ExecState* exec, const ArgList& args) } #if ENABLE(DATABASE) -JSValuePtr JSInspectorController::databaseTableNames(ExecState* exec, const ArgList& args) +JSValue JSInspectorController::databaseTableNames(ExecState* exec, const ArgList& args) { if (args.size() < 1) return jsUndefined(); - JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(args.at(exec, 0)); + JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(args.at(0)); if (!wrapper) return jsUndefined(); @@ -215,7 +164,7 @@ JSValuePtr JSInspectorController::databaseTableNames(ExecState* exec, const ArgL if (!database) return jsUndefined(); - ArgList result; + MarkedArgumentBuffer result; Vector<String> tableNames = database->tableNames(); unsigned length = tableNames.size(); @@ -226,18 +175,18 @@ JSValuePtr JSInspectorController::databaseTableNames(ExecState* exec, const ArgL } #endif -JSValuePtr JSInspectorController::inspectedWindow(ExecState*, const ArgList&) +JSValue JSInspectorController::inspectedWindow(ExecState*, const ArgList&) { JSDOMWindow* inspectedWindow = toJSDOMWindow(impl()->inspectedPage()->mainFrame()); return JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), inspectedWindow); } -JSValuePtr JSInspectorController::setting(ExecState* exec, const ArgList& args) +JSValue JSInspectorController::setting(ExecState* exec, const ArgList& args) { if (args.size() < 1) return jsUndefined(); - String key = args.at(exec, 0).toString(exec); + String key = args.at(0).toString(exec); if (exec->hadException()) return jsUndefined(); @@ -256,7 +205,7 @@ JSValuePtr JSInspectorController::setting(ExecState* exec, const ArgList& args) case InspectorController::Setting::BooleanType: return jsBoolean(setting.booleanValue()); case InspectorController::Setting::StringVectorType: { - ArgList stringsArray; + MarkedArgumentBuffer stringsArray; const Vector<String>& strings = setting.stringVector(); const unsigned length = strings.size(); for (unsigned i = 0; i < length; ++i) @@ -266,18 +215,18 @@ JSValuePtr JSInspectorController::setting(ExecState* exec, const ArgList& args) } } -JSValuePtr JSInspectorController::setSetting(ExecState* exec, const ArgList& args) +JSValue JSInspectorController::setSetting(ExecState* exec, const ArgList& args) { if (args.size() < 2) return jsUndefined(); - String key = args.at(exec, 0).toString(exec); + String key = args.at(0).toString(exec); if (exec->hadException()) return jsUndefined(); InspectorController::Setting setting; - JSValuePtr value = args.at(exec, 0); + JSValue value = args.at(1); if (value.isUndefined() || value.isNull()) { // Do nothing. The setting is already NoType. ASSERT(setting.type() == InspectorController::Setting::NoType); @@ -309,15 +258,17 @@ JSValuePtr JSInspectorController::setSetting(ExecState* exec, const ArgList& arg return jsUndefined(); } -JSValuePtr JSInspectorController::wrapCallback(ExecState* exec, const ArgList& args) +JSValue JSInspectorController::wrapCallback(ExecState* exec, const ArgList& args) { if (args.size() < 1) return jsUndefined(); - return JSInspectorCallbackWrapper::wrap(exec, args.at(exec, 0)); + return JSInspectorCallbackWrapper::wrap(exec, args.at(0)); } -JSValuePtr JSInspectorController::currentCallFrame(ExecState* exec, const ArgList&) +#if ENABLE(JAVASCRIPT_DEBUGGER) + +JSValue JSInspectorController::currentCallFrame(ExecState* exec, const ArgList&) { JavaScriptCallFrame* callFrame = impl()->currentCallFrame(); if (!callFrame || !callFrame->isValid()) @@ -330,4 +281,18 @@ JSValuePtr JSInspectorController::currentCallFrame(ExecState* exec, const ArgLis return JSInspectedObjectWrapper::wrap(globalExec, toJS(exec, callFrame)); } +JSValue JSInspectorController::profiles(JSC::ExecState* exec, const JSC::ArgList&) +{ + JSLock lock(false); + MarkedArgumentBuffer result; + const Vector<RefPtr<Profile> >& profiles = impl()->profiles(); + + for (size_t i = 0; i < profiles.size(); ++i) + result.append(toJS(exec, profiles[i].get())); + + return constructArray(exec, result); +} + +#endif + } // namespace WebCore diff --git a/WebCore/bindings/js/JSJavaScriptCallFrameCustom.cpp b/WebCore/bindings/js/JSJavaScriptCallFrameCustom.cpp index 7c99120..08ecf2b 100644 --- a/WebCore/bindings/js/JSJavaScriptCallFrameCustom.cpp +++ b/WebCore/bindings/js/JSJavaScriptCallFrameCustom.cpp @@ -26,6 +26,8 @@ #include "config.h" #include "JSJavaScriptCallFrame.h" +#if ENABLE(JAVASCRIPT_DEBUGGER) + #include "JavaScriptCallFrame.h" #include <runtime/ArrayPrototype.h> @@ -33,10 +35,10 @@ using namespace JSC; namespace WebCore { -JSValuePtr JSJavaScriptCallFrame::evaluate(ExecState* exec, const ArgList& args) +JSValue JSJavaScriptCallFrame::evaluate(ExecState* exec, const ArgList& args) { - JSValuePtr exception = noValue(); - JSValuePtr result = impl()->evaluate(args.at(exec, 0).toString(exec), exception); + JSValue exception; + JSValue result = impl()->evaluate(args.at(0).toString(exec), exception); if (exception) exec->setException(exception); @@ -44,12 +46,12 @@ JSValuePtr JSJavaScriptCallFrame::evaluate(ExecState* exec, const ArgList& args) return result; } -JSValuePtr JSJavaScriptCallFrame::thisObject(ExecState*) const +JSValue JSJavaScriptCallFrame::thisObject(ExecState*) const { return impl()->thisObject() ? impl()->thisObject() : jsNull(); } -JSValuePtr JSJavaScriptCallFrame::type(ExecState* exec) const +JSValue JSJavaScriptCallFrame::type(ExecState* exec) const { switch (impl()->type()) { case DebuggerCallFrame::FunctionType: @@ -62,7 +64,7 @@ JSValuePtr JSJavaScriptCallFrame::type(ExecState* exec) const return jsNull(); } -JSValuePtr JSJavaScriptCallFrame::scopeChain(ExecState* exec) const +JSValue JSJavaScriptCallFrame::scopeChain(ExecState* exec) const { if (!impl()->scopeChain()) return jsNull(); @@ -74,7 +76,7 @@ JSValuePtr JSJavaScriptCallFrame::scopeChain(ExecState* exec) const // we must always have something in the scope chain ASSERT(iter != end); - ArgList list; + MarkedArgumentBuffer list; do { list.append(*iter); ++iter; @@ -84,3 +86,5 @@ JSValuePtr JSJavaScriptCallFrame::scopeChain(ExecState* exec) const } } // namespace WebCore + +#endif // ENABLE(JAVASCRIPT_DEBUGGER) diff --git a/WebCore/bindings/js/JSLazyEventListener.cpp b/WebCore/bindings/js/JSLazyEventListener.cpp index 3c80efe..f7c74ae 100644 --- a/WebCore/bindings/js/JSLazyEventListener.cpp +++ b/WebCore/bindings/js/JSLazyEventListener.cpp @@ -23,19 +23,25 @@ #include "Frame.h" #include "JSNode.h" #include <runtime/FunctionConstructor.h> +#include <runtime/JSLock.h> +#include <wtf/RefCountedLeakCounter.h> using namespace JSC; namespace WebCore { -JSLazyEventListener::JSLazyEventListener(LazyEventListenerType type, const String& functionName, const String& code, JSDOMGlobalObject* globalObject, Node* node, int lineNumber) - : JSProtectedEventListener(0, globalObject, true) +#ifndef NDEBUG +static WTF::RefCountedLeakCounter eventListenerCounter("JSLazyEventListener"); +#endif + +JSLazyEventListener::JSLazyEventListener(const String& functionName, const String& eventParameterName, const String& code, JSDOMGlobalObject* globalObject, Node* node, int lineNumber) + : JSEventListener(0, globalObject, true) , m_functionName(functionName) + , m_eventParameterName(eventParameterName) , m_code(code) , m_parsed(false) , m_lineNumber(lineNumber) , m_originalNode(node) - , m_type(type) { // We don't retain the original node because we assume it // will stay alive as long as this handler object is around @@ -47,26 +53,23 @@ JSLazyEventListener::JSLazyEventListener(LazyEventListenerType type, const Strin // a setAttribute call from JavaScript, so make the line number 1 in that case. if (m_lineNumber == 0) m_lineNumber = 1; + +#ifndef NDEBUG + eventListenerCounter.increment(); +#endif } -JSObject* JSLazyEventListener::function() const +JSLazyEventListener::~JSLazyEventListener() { - parseCode(); - return m_listener; +#ifndef NDEBUG + eventListenerCounter.decrement(); +#endif } -static inline JSValuePtr eventParameterName(JSLazyEventListener::LazyEventListenerType type, ExecState* exec) +JSObject* JSLazyEventListener::jsFunction() const { - switch (type) { - case JSLazyEventListener::HTMLLazyEventListener: - return jsNontrivialString(exec, "event"); -#if ENABLE(SVG) - case JSLazyEventListener::SVGLazyEventListener: - return jsNontrivialString(exec, "evt"); -#endif - } - ASSERT_NOT_REACHED(); - return jsUndefined(); + parseCode(); + return m_jsFunction; } void JSLazyEventListener::parseCode() const @@ -75,7 +78,7 @@ void JSLazyEventListener::parseCode() const return; if (m_globalObject->scriptExecutionContext()->isDocument()) { - JSDOMWindow* window = static_cast<JSDOMWindow*>(m_globalObject.get()); + JSDOMWindow* window = static_cast<JSDOMWindow*>(m_globalObject); Frame* frame = window->impl()->frame(); if (!frame) return; @@ -89,43 +92,38 @@ void JSLazyEventListener::parseCode() const ExecState* exec = m_globalObject->globalExec(); - ArgList args; + MarkedArgumentBuffer args; UString sourceURL(m_globalObject->scriptExecutionContext()->url().string()); - args.append(eventParameterName(m_type, exec)); + args.append(jsNontrivialString(exec, m_eventParameterName)); args.append(jsString(exec, m_code)); // FIXME: Passing the document's URL to construct is not always correct, since this event listener might // have been added with setAttribute from a script, and we should pass String() in that case. - m_listener = constructFunction(exec, args, Identifier(exec, m_functionName), sourceURL, m_lineNumber); // FIXME: is globalExec ok? + m_jsFunction = constructFunction(exec, args, Identifier(exec, m_functionName), sourceURL, m_lineNumber); // FIXME: is globalExec ok? - JSFunction* listenerAsFunction = static_cast<JSFunction*>(m_listener.get()); + JSFunction* listenerAsFunction = static_cast<JSFunction*>(m_jsFunction); if (exec->hadException()) { exec->clearException(); // failed to parse, so let's just make this listener a no-op - m_listener = 0; + m_jsFunction = 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(); - JSValuePtr thisObj = toJS(exec, m_originalNode); + JSValue thisObj = toJS(exec, m_originalNode); if (thisObj.isObject()) { static_cast<JSNode*>(asObject(thisObj))->pushEventHandlerScope(exec, scope); listenerAsFunction->setScope(scope); } } - // no more need to keep the unparsed code around + // Since we only parse once, there's no need to keep data used for parsing around anymore. m_functionName = String(); m_code = String(); - - if (m_listener) { - ASSERT(isInline()); - JSDOMWindow::ProtectedListenersMap& listeners = m_globalObject->jsProtectedInlineEventListeners(); - listeners.set(m_listener, const_cast<JSLazyEventListener*>(this)); - } + m_eventParameterName = String(); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSLazyEventListener.h b/WebCore/bindings/js/JSLazyEventListener.h index 5424883..a5304cf 100644 --- a/WebCore/bindings/js/JSLazyEventListener.h +++ b/WebCore/bindings/js/JSLazyEventListener.h @@ -27,35 +27,28 @@ namespace WebCore { class Node; - class JSLazyEventListener : public JSProtectedEventListener { + class JSLazyEventListener : public JSEventListener { public: - enum LazyEventListenerType { - HTMLLazyEventListener -#if ENABLE(SVG) - , SVGLazyEventListener -#endif - }; - - static PassRefPtr<JSLazyEventListener> create(LazyEventListenerType type, const String& functionName, const String& code, JSDOMGlobalObject* globalObject, Node* node, int lineNumber) + static PassRefPtr<JSLazyEventListener> create(const String& functionName, const String& eventParameterName, const String& code, JSDOMGlobalObject* globalObject, Node* node, int lineNumber) { - return adoptRef(new JSLazyEventListener(type, functionName, code, globalObject, node, lineNumber)); + return adoptRef(new JSLazyEventListener(functionName, eventParameterName, code, globalObject, node, lineNumber)); } + virtual ~JSLazyEventListener(); private: - JSLazyEventListener(LazyEventListenerType, const String& functionName, const String& code, JSDOMGlobalObject*, Node*, int lineNumber); + JSLazyEventListener(const String& functionName, const String& eventParameterName, const String& code, JSDOMGlobalObject*, Node*, int lineNumber); - virtual JSC::JSObject* function() const; + virtual JSC::JSObject* jsFunction() const; virtual bool wasCreatedFromMarkup() const { return true; } void parseCode() const; mutable String m_functionName; + mutable String m_eventParameterName; mutable String m_code; mutable bool m_parsed; int m_lineNumber; Node* m_originalNode; - - LazyEventListenerType m_type; }; } // namespace WebCore diff --git a/WebCore/bindings/js/JSLocationCustom.cpp b/WebCore/bindings/js/JSLocationCustom.cpp index a99a105..9c5a834 100644 --- a/WebCore/bindings/js/JSLocationCustom.cpp +++ b/WebCore/bindings/js/JSLocationCustom.cpp @@ -37,17 +37,17 @@ using namespace JSC; namespace WebCore { -static JSValuePtr nonCachingStaticReplaceFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) +static JSValue nonCachingStaticReplaceFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) { return new (exec) PrototypeFunction(exec, 1, propertyName, jsLocationPrototypeFunctionReplace); } -static JSValuePtr nonCachingStaticReloadFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) +static JSValue nonCachingStaticReloadFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) { return new (exec) PrototypeFunction(exec, 0, propertyName, jsLocationPrototypeFunctionReload); } -static JSValuePtr nonCachingStaticAssignFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) +static JSValue nonCachingStaticAssignFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&) { return new (exec) PrototypeFunction(exec, 1, propertyName, jsLocationPrototypeFunctionAssign); } @@ -93,12 +93,15 @@ bool JSLocation::customGetOwnPropertySlot(ExecState* exec, const Identifier& pro return true; } -bool JSLocation::customPut(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot) +bool JSLocation::customPut(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { Frame* frame = impl()->frame(); if (!frame) return true; + if (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf) + return true; + bool sameDomainAccess = allowsAccessFromFrame(exec, frame); const HashEntry* entry = JSLocation::s_info.propHashTable(exec)->entry(exec, propertyName); @@ -133,31 +136,39 @@ bool JSLocation::customGetPropertyNames(ExecState* exec, PropertyNameArray&) return false; } +void JSLocation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction) +{ + if (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf) + return; + Base::defineGetter(exec, propertyName, getterFunction); +} + static void navigateIfAllowed(ExecState* exec, Frame* frame, const KURL& url, bool lockHistory, bool lockBackForwardList) { - Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); - if (!url.protocolIs("javascript") || allowsAccessFromFrame(exec, frame)) { - bool userGesture = activeFrame->script()->processingUserGesture(); - frame->loader()->scheduleLocationChange(url.string(), activeFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, userGesture); - } + Frame* lexicalFrame = toLexicalFrame(exec); + if (!lexicalFrame) + return; + + if (!protocolIsJavaScript(url) || allowsAccessFromFrame(exec, frame)) + frame->loader()->scheduleLocationChange(url.string(), lexicalFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, processingUserGesture(exec)); } -void JSLocation::setHref(ExecState* exec, JSValuePtr value) +void JSLocation::setHref(ExecState* exec, JSValue value) { Frame* frame = impl()->frame(); ASSERT(frame); - Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); - if (!activeFrame) + if (!shouldAllowNavigation(exec, frame)) return; - if (!activeFrame->loader()->shouldAllowNavigation(frame)) + + KURL url = completeURL(exec, value.toString(exec)); + if (url.isNull()) return; - KURL url = activeFrame->loader()->completeURL(value.toString(exec)); navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); } -void JSLocation::setProtocol(ExecState* exec, JSValuePtr value) +void JSLocation::setProtocol(ExecState* exec, JSValue value) { Frame* frame = impl()->frame(); ASSERT(frame); @@ -168,7 +179,7 @@ void JSLocation::setProtocol(ExecState* exec, JSValuePtr value) navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); } -void JSLocation::setHost(ExecState* exec, JSValuePtr value) +void JSLocation::setHost(ExecState* exec, JSValue value) { Frame* frame = impl()->frame(); ASSERT(frame); @@ -179,7 +190,7 @@ void JSLocation::setHost(ExecState* exec, JSValuePtr value) navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); } -void JSLocation::setHostname(ExecState* exec, JSValuePtr value) +void JSLocation::setHostname(ExecState* exec, JSValue value) { Frame* frame = impl()->frame(); ASSERT(frame); @@ -190,7 +201,7 @@ void JSLocation::setHostname(ExecState* exec, JSValuePtr value) navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); } -void JSLocation::setPort(ExecState* exec, JSValuePtr value) +void JSLocation::setPort(ExecState* exec, JSValue value) { Frame* frame = impl()->frame(); ASSERT(frame); @@ -206,7 +217,7 @@ void JSLocation::setPort(ExecState* exec, JSValuePtr value) navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); } -void JSLocation::setPathname(ExecState* exec, JSValuePtr value) +void JSLocation::setPathname(ExecState* exec, JSValue value) { Frame* frame = impl()->frame(); ASSERT(frame); @@ -217,7 +228,7 @@ void JSLocation::setPathname(ExecState* exec, JSValuePtr value) navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); } -void JSLocation::setSearch(ExecState* exec, JSValuePtr value) +void JSLocation::setSearch(ExecState* exec, JSValue value) { Frame* frame = impl()->frame(); ASSERT(frame); @@ -228,7 +239,7 @@ void JSLocation::setSearch(ExecState* exec, JSValuePtr value) navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); } -void JSLocation::setHash(ExecState* exec, JSValuePtr value) +void JSLocation::setHash(ExecState* exec, JSValue value) { Frame* frame = impl()->frame(); ASSERT(frame); @@ -245,65 +256,71 @@ void JSLocation::setHash(ExecState* exec, JSValuePtr value) navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); } -JSValuePtr JSLocation::replace(ExecState* exec, const ArgList& args) +JSValue JSLocation::replace(ExecState* exec, const ArgList& args) { Frame* frame = impl()->frame(); if (!frame) return jsUndefined(); - Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); - if (!activeFrame) + if (!shouldAllowNavigation(exec, frame)) return jsUndefined(); - if (!activeFrame->loader()->shouldAllowNavigation(frame)) + + KURL url = completeURL(exec, args.at(0).toString(exec)); + if (url.isNull()) return jsUndefined(); - navigateIfAllowed(exec, frame, activeFrame->loader()->completeURL(args.at(exec, 0).toString(exec)), true, true); + navigateIfAllowed(exec, frame, url, true, true); return jsUndefined(); } -JSValuePtr JSLocation::reload(ExecState* exec, const ArgList&) +JSValue JSLocation::reload(ExecState* exec, const ArgList&) { Frame* frame = impl()->frame(); - if (!frame) - return jsUndefined(); - - JSDOMWindow* window = toJSDOMWindow(frame); - if (!window->allowsAccessFrom(exec)) + if (!frame || !allowsAccessFromFrame(exec, frame)) return jsUndefined(); - if (!frame->loader()->url().protocolIs("javascript") || (window && window->allowsAccessFrom(exec))) { - bool userGesture = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame()->script()->processingUserGesture(); - frame->loader()->scheduleRefresh(userGesture); - } + if (!protocolIsJavaScript(frame->loader()->url())) + frame->loader()->scheduleRefresh(processingUserGesture(exec)); return jsUndefined(); } -JSValuePtr JSLocation::assign(ExecState* exec, const ArgList& args) +JSValue JSLocation::assign(ExecState* exec, const ArgList& args) { Frame* frame = impl()->frame(); if (!frame) return jsUndefined(); - Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame(); - if (!activeFrame) + if (!shouldAllowNavigation(exec, frame)) return jsUndefined(); - if (!activeFrame->loader()->shouldAllowNavigation(frame)) + + KURL url = completeURL(exec, args.at(0).toString(exec)); + if (url.isNull()) return jsUndefined(); // We want a new history item if this JS was called via a user gesture - navigateIfAllowed(exec, frame, activeFrame->loader()->completeURL(args.at(exec, 0).toString(exec)), !frame->script()->anyPageIsProcessingUserGesture(), false); + navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false); return jsUndefined(); } -JSValuePtr JSLocation::toString(ExecState* exec, const ArgList&) +JSValue JSLocation::toString(ExecState* exec, const ArgList&) { Frame* frame = impl()->frame(); - if (!frame) - return jsUndefined(); - if (!allowsAccessFromFrame(exec, frame)) + if (!frame || !allowsAccessFromFrame(exec, frame)) return jsUndefined(); return jsString(exec, impl()->toString()); } +bool JSLocationPrototype::customPut(ExecState* exec, const Identifier& propertyName, JSValue, PutPropertySlot&) +{ + return (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf); +} + +void JSLocationPrototype::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction) +{ + if (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf) + return; + Base::defineGetter(exec, propertyName, getterFunction); +} + } // namespace WebCore diff --git a/WebCore/bindings/js/JSMessageChannelConstructor.cpp b/WebCore/bindings/js/JSMessageChannelConstructor.cpp index f5b73df..495bd53 100644 --- a/WebCore/bindings/js/JSMessageChannelConstructor.cpp +++ b/WebCore/bindings/js/JSMessageChannelConstructor.cpp @@ -29,11 +29,6 @@ #include "Document.h" #include "JSDocument.h" #include "JSMessageChannel.h" -#ifdef ANDROID_FIX // these are generated files, need to check ENABLE(WORKERS) -#if ENABLE(WORKERS) -#include "JSWorkerContext.h" -#endif -#endif #include "MessageChannel.h" using namespace JSC; @@ -42,11 +37,11 @@ namespace WebCore { const ClassInfo JSMessageChannelConstructor::s_info = { "MessageChannelConstructor", 0, 0, 0 }; -JSMessageChannelConstructor::JSMessageChannelConstructor(ExecState* exec, ScriptExecutionContext* scriptExecutionContext) +JSMessageChannelConstructor::JSMessageChannelConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) : DOMObject(JSMessageChannelConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) - , m_globalObject(toJSDOMGlobalObject(scriptExecutionContext)) + , m_globalObject(globalObject) { - putDirect(exec->propertyNames().prototype, JSMessageChannelPrototype::self(exec), None); + putDirect(exec->propertyNames().prototype, JSMessageChannelPrototype::self(exec, exec->lexicalGlobalObject()), None); } JSMessageChannelConstructor::~JSMessageChannelConstructor() @@ -66,7 +61,11 @@ ConstructType JSMessageChannelConstructor::getConstructData(ConstructData& const JSObject* JSMessageChannelConstructor::construct(ExecState* exec, JSObject* constructor, const ArgList&) { - return asObject(toJS(exec, MessageChannel::create(static_cast<JSMessageChannelConstructor*>(constructor)->scriptExecutionContext()))); + ScriptExecutionContext* context = static_cast<JSMessageChannelConstructor*>(constructor)->scriptExecutionContext(); + if (!context) + return throwError(exec, ReferenceError, "MessageChannel constructor associated document is unavailable"); + + return asObject(toJS(exec, MessageChannel::create(context))); } void JSMessageChannelConstructor::mark() diff --git a/WebCore/bindings/js/JSMessageChannelConstructor.h b/WebCore/bindings/js/JSMessageChannelConstructor.h index 2691777..90c29a3 100644 --- a/WebCore/bindings/js/JSMessageChannelConstructor.h +++ b/WebCore/bindings/js/JSMessageChannelConstructor.h @@ -32,7 +32,7 @@ namespace WebCore { class JSMessageChannelConstructor : public DOMObject { public: - JSMessageChannelConstructor(JSC::ExecState*, ScriptExecutionContext*); + JSMessageChannelConstructor(JSC::ExecState*, JSDOMGlobalObject*); virtual ~JSMessageChannelConstructor(); virtual const JSC::ClassInfo* classInfo() const { return &s_info; } static const JSC::ClassInfo s_info; diff --git a/WebCore/bindings/js/JSMessagePortCustom.cpp b/WebCore/bindings/js/JSMessagePortCustom.cpp index 394f9b1..f4809ae 100644 --- a/WebCore/bindings/js/JSMessagePortCustom.cpp +++ b/WebCore/bindings/js/JSMessagePortCustom.cpp @@ -45,7 +45,7 @@ void JSMessagePort::mark() markIfNotNull(m_impl->onmessage()); markIfNotNull(m_impl->onclose()); - if (MessagePort* entangledPort = m_impl->entangledPort()) { + if (MessagePortProxy* entangledPort = m_impl->entangledPort()) { DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), entangledPort); if (wrapper && !wrapper->marked()) wrapper->mark(); @@ -56,39 +56,39 @@ void JSMessagePort::mark() 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) - (*vecIter)->mark(); + (*vecIter)->markJSFunction(); } } -JSValuePtr JSMessagePort::startConversation(ExecState* exec, const ArgList& args) +JSValue JSMessagePort::startConversation(ExecState* exec, const ArgList& args) { JSDOMGlobalObject* globalObject = static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()); - const UString& message = args.at(exec, 0).toString(exec); + const UString& message = args.at(0).toString(exec); return toJS(exec, impl()->startConversation(globalObject->scriptExecutionContext(), message).get()); } -JSValuePtr JSMessagePort::addEventListener(ExecState* exec, const ArgList& args) +JSValue JSMessagePort::addEventListener(ExecState* exec, const ArgList& args) { JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1)); + RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(args.at(1)); if (!listener) return jsUndefined(); - impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec)); + impl()->addEventListener(args.at(0).toString(exec), listener.release(), args.at(2).toBoolean(exec)); return jsUndefined(); } -JSValuePtr JSMessagePort::removeEventListener(ExecState* exec, const ArgList& args) +JSValue JSMessagePort::removeEventListener(ExecState* exec, const ArgList& args) { JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - JSEventListener* listener = globalObject->findJSEventListener(exec, args.at(exec, 1)); + JSEventListener* listener = globalObject->findJSEventListener(args.at(1)); if (!listener) return jsUndefined(); - impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec)); + impl()->removeEventListener(args.at(0).toString(exec), listener, args.at(2).toBoolean(exec)); return jsUndefined(); } diff --git a/WebCore/bindings/js/JSMimeTypeArrayCustom.cpp b/WebCore/bindings/js/JSMimeTypeArrayCustom.cpp index 5338d5b..c90dadd 100644 --- a/WebCore/bindings/js/JSMimeTypeArrayCustom.cpp +++ b/WebCore/bindings/js/JSMimeTypeArrayCustom.cpp @@ -33,7 +33,7 @@ bool JSMimeTypeArray::canGetItemsForName(ExecState*, MimeTypeArray* mimeTypeArra return mimeTypeArray->canGetItemsForName(propertyName); } -JSValuePtr JSMimeTypeArray::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSMimeTypeArray::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { JSMimeTypeArray* thisObj = static_cast<JSMimeTypeArray*>(asObject(slot.slotBase())); return toJS(exec, thisObj->impl()->namedItem(propertyName)); diff --git a/WebCore/bindings/js/JSNamedNodeMapCustom.cpp b/WebCore/bindings/js/JSNamedNodeMapCustom.cpp index e7b0764..7bd95b4 100644 --- a/WebCore/bindings/js/JSNamedNodeMapCustom.cpp +++ b/WebCore/bindings/js/JSNamedNodeMapCustom.cpp @@ -41,7 +41,7 @@ bool JSNamedNodeMap::canGetItemsForName(ExecState*, NamedNodeMap* impl, const Id return impl->getNamedItem(propertyName); } -JSValuePtr JSNamedNodeMap::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSNamedNodeMap::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { JSNamedNodeMap* thisObj = static_cast<JSNamedNodeMap*>(asObject(slot.slotBase())); return toJS(exec, thisObj->impl()->getNamedItem(propertyName)); diff --git a/WebCore/bindings/js/JSNamedNodesCollection.cpp b/WebCore/bindings/js/JSNamedNodesCollection.cpp index 8068a1d..93a8937 100644 --- a/WebCore/bindings/js/JSNamedNodesCollection.cpp +++ b/WebCore/bindings/js/JSNamedNodesCollection.cpp @@ -29,7 +29,7 @@ #include "AtomicString.h" #include "Element.h" #include "JSNode.h" -#include "NamedAttrMap.h" +#include "NamedNodeMap.h" namespace WebCore { @@ -48,13 +48,13 @@ JSNamedNodesCollection::JSNamedNodesCollection(ExecState* exec, const Vector<Ref { } -JSValuePtr JSNamedNodesCollection::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) +JSValue JSNamedNodesCollection::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) { JSNamedNodesCollection* thisObj = static_cast<JSNamedNodesCollection*>(asObject(slot.slotBase())); return jsNumber(exec, thisObj->m_nodes->size()); } -JSValuePtr JSNamedNodesCollection::indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) +JSValue JSNamedNodesCollection::indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) { JSNamedNodesCollection *thisObj = static_cast<JSNamedNodesCollection*>(asObject(slot.slotBase())); return toJS(exec, (*thisObj->m_nodes)[slot.index()].get()); diff --git a/WebCore/bindings/js/JSNamedNodesCollection.h b/WebCore/bindings/js/JSNamedNodesCollection.h index 19f194b..3bbc102 100644 --- a/WebCore/bindings/js/JSNamedNodesCollection.h +++ b/WebCore/bindings/js/JSNamedNodesCollection.h @@ -44,19 +44,19 @@ namespace WebCore { virtual const JSC::ClassInfo* classInfo() const { return &s_info; } static const JSC::ClassInfo s_info; - static JSC::ObjectPrototype* createPrototype(JSC::ExecState* exec) + static JSC::ObjectPrototype* createPrototype(JSC::ExecState*, JSC::JSGlobalObject* globalObject) { - return exec->lexicalGlobalObject()->objectPrototype(); + return globalObject->objectPrototype(); } - static PassRefPtr<JSC::Structure> createStructure(JSC::JSValuePtr prototype) + static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) { return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType)); } private: - static JSC::JSValuePtr lengthGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); - static JSC::JSValuePtr indexGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); + static JSC::JSValue lengthGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); + static JSC::JSValue indexGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); OwnPtr<Vector<RefPtr<Node> > > m_nodes; }; diff --git a/WebCore/bindings/js/JSNavigatorCustom.cpp b/WebCore/bindings/js/JSNavigatorCustom.cpp index a7b6194..ea6cceb 100644 --- a/WebCore/bindings/js/JSNavigatorCustom.cpp +++ b/WebCore/bindings/js/JSNavigatorCustom.cpp @@ -2,7 +2,7 @@ * 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. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All Rights Reserved. * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * * This library is free software; you can redistribute it and/or @@ -23,92 +23,12 @@ #include "config.h" #include "JSNavigator.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "KURL.h" #include "Navigator.h" -#include "Settings.h" namespace WebCore { using namespace JSC; -static bool needsYouTubeQuirk(ExecState*, Frame*); - -#if 1 - -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". - JSFunction* function = exec->function(); - if (!function) - return false; - DEFINE_STATIC_LOCAL(const Identifier, isWindowsFunctionName, (exec, "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; - JSFunction* callingFunction = callingExec->function(); - if (!callingFunction) - return false; - JSObject* thisObject = callingExec->thisValue(); - if (!thisObject) - return false; - DEFINE_STATIC_LOCAL(const Identifier, isSafariFunction, (exec, "isSafari")); - JSValuePtr isSafariFunction = thisObject->getDirect(isSafariFunctionName); - if (isSafariFunction != callingFunction) - return false; - - Document* document = frame->document(); - - // 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 - -JSValuePtr JSNavigator::appVersion(ExecState* exec) const -{ - Navigator* imp = static_cast<Navigator*>(impl()); - Frame* frame = imp->frame(); - if (!frame) - return jsString(exec, ""); - - if (needsYouTubeQuirk(exec, frame)) - return jsString(exec, ""); - return jsString(exec, imp->appVersion()); -} - void JSNavigator::mark() { Base::mark(); diff --git a/WebCore/bindings/js/JSNodeCustom.cpp b/WebCore/bindings/js/JSNodeCustom.cpp index 8f4d2c1..79ac6b7 100644 --- a/WebCore/bindings/js/JSNodeCustom.cpp +++ b/WebCore/bindings/js/JSNodeCustom.cpp @@ -52,6 +52,7 @@ #include "Node.h" #include "Notation.h" #include "ProcessingInstruction.h" +#include "RegisteredEventListener.h" #include "Text.h" #include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> @@ -67,66 +68,66 @@ namespace WebCore { typedef int ExpectionCode; -JSValuePtr JSNode::insertBefore(ExecState* exec, const ArgList& args) +JSValue JSNode::insertBefore(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; - bool ok = impl()->insertBefore(toNode(args.at(exec, 0)), toNode(args.at(exec, 1)), ec, true); + bool ok = impl()->insertBefore(toNode(args.at(0)), toNode(args.at(1)), ec, true); setDOMException(exec, ec); if (ok) - return args.at(exec, 0); + return args.at(0); return jsNull(); } -JSValuePtr JSNode::replaceChild(ExecState* exec, const ArgList& args) +JSValue JSNode::replaceChild(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; - bool ok = impl()->replaceChild(toNode(args.at(exec, 0)), toNode(args.at(exec, 1)), ec, true); + bool ok = impl()->replaceChild(toNode(args.at(0)), toNode(args.at(1)), ec, true); setDOMException(exec, ec); if (ok) - return args.at(exec, 1); + return args.at(1); return jsNull(); } -JSValuePtr JSNode::removeChild(ExecState* exec, const ArgList& args) +JSValue JSNode::removeChild(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; - bool ok = impl()->removeChild(toNode(args.at(exec, 0)), ec); + bool ok = impl()->removeChild(toNode(args.at(0)), ec); setDOMException(exec, ec); if (ok) - return args.at(exec, 0); + return args.at(0); return jsNull(); } -JSValuePtr JSNode::appendChild(ExecState* exec, const ArgList& args) +JSValue JSNode::appendChild(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; - bool ok = impl()->appendChild(toNode(args.at(exec, 0)), ec, true); + bool ok = impl()->appendChild(toNode(args.at(0)), ec, true); setDOMException(exec, ec); if (ok) - return args.at(exec, 0); + return args.at(0); return jsNull(); } -JSValuePtr JSNode::addEventListener(ExecState* exec, const ArgList& args) +JSValue JSNode::addEventListener(ExecState* exec, const ArgList& args) { JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - if (RefPtr<JSProtectedEventListener> listener = globalObject->findOrCreateJSProtectedEventListener(exec, args.at(exec, 1))) - impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec)); + if (RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(args.at(1))) + impl()->addEventListener(args.at(0).toString(exec), listener.release(), args.at(2).toBoolean(exec)); return jsUndefined(); } -JSValuePtr JSNode::removeEventListener(ExecState* exec, const ArgList& args) +JSValue JSNode::removeEventListener(ExecState* exec, const ArgList& args) { JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - if (JSProtectedEventListener* listener = globalObject->findJSProtectedEventListener(args.at(exec, 1))) - impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec)); + if (JSEventListener* listener = globalObject->findJSEventListener(args.at(1))) + impl()->removeEventListener(args.at(0).toString(exec), listener, args.at(2).toBoolean(exec)); return jsUndefined(); } @@ -141,16 +142,16 @@ void JSNode::mark() Node* node = m_impl.get(); - // Nodes in the document are kept alive by JSDocument::mark, - // so we have no special responsibilities and can just call the base class here. + // Nodes in the document are kept alive by JSDocument::mark, so, if we're in + // the document, we need to mark the document, but we don't need to explicitly + // mark any other nodes. if (node->inDocument()) { - // But if the document isn't marked we have to mark it to ensure that - // nodes reachable from this one are also marked + DOMObject::mark(); + markEventListeners(node->eventListeners()); if (Document* doc = node->ownerDocument()) if (DOMObject* docWrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), doc)) if (!docWrapper->marked()) docWrapper->mark(); - DOMObject::mark(); return; } @@ -160,14 +161,15 @@ void JSNode::mark() 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. + // Nodes in a subtree are marked by the tree's root, so, if the root is already + // marking the tree, we don't need to explicitly mark any other nodes. if (root->inSubtreeMark()) { DOMObject::mark(); + markEventListeners(node->eventListeners()); return; } - // Mark the whole tree; use the global set of roots to avoid reentering. + // Mark the whole tree subtree. root->setInSubtreeMark(true); for (Node* nodeToMark = root; nodeToMark; nodeToMark = nodeToMark->traverseNextNode()) { JSNode* wrapper = getCachedDOMNodeWrapper(m_impl->document(), nodeToMark); @@ -190,7 +192,7 @@ void JSNode::mark() ASSERT(marked()); } -static ALWAYS_INLINE JSValuePtr createWrapper(ExecState* exec, Node* node) +static ALWAYS_INLINE JSValue createWrapper(ExecState* exec, Node* node) { ASSERT(node); ASSERT(!getCachedDOMNodeWrapper(node->document(), node)); @@ -247,7 +249,7 @@ static ALWAYS_INLINE JSValuePtr createWrapper(ExecState* exec, Node* node) return wrapper; } -JSValuePtr toJSNewlyCreated(ExecState* exec, Node* node) +JSValue toJSNewlyCreated(ExecState* exec, Node* node) { if (!node) return jsNull(); @@ -255,7 +257,7 @@ JSValuePtr toJSNewlyCreated(ExecState* exec, Node* node) return createWrapper(exec, node); } -JSValuePtr toJS(ExecState* exec, Node* node) +JSValue toJS(ExecState* exec, Node* node) { if (!node) return jsNull(); diff --git a/WebCore/bindings/js/JSNodeFilterCondition.cpp b/WebCore/bindings/js/JSNodeFilterCondition.cpp index f4b9e0c..f5d4d5c 100644 --- a/WebCore/bindings/js/JSNodeFilterCondition.cpp +++ b/WebCore/bindings/js/JSNodeFilterCondition.cpp @@ -31,7 +31,7 @@ using namespace JSC; ASSERT_CLASS_FITS_IN_CELL(JSNodeFilterCondition); -JSNodeFilterCondition::JSNodeFilterCondition(JSValuePtr filter) +JSNodeFilterCondition::JSNodeFilterCondition(JSValue filter) : m_filter(filter) { } @@ -60,12 +60,12 @@ short JSNodeFilterCondition::acceptNode(JSC::ExecState* exec, Node* filterNode) if (!exec) return NodeFilter::FILTER_REJECT; - ArgList args; + MarkedArgumentBuffer args; args.append(toJS(exec, filterNode)); if (exec->hadException()) return NodeFilter::FILTER_REJECT; - JSValuePtr result = call(exec, m_filter, callType, callData, m_filter, args); + JSValue result = call(exec, m_filter, callType, callData, m_filter, args); if (exec->hadException()) return NodeFilter::FILTER_REJECT; diff --git a/WebCore/bindings/js/JSNodeFilterCondition.h b/WebCore/bindings/js/JSNodeFilterCondition.h index b6be44b..3d591c6 100644 --- a/WebCore/bindings/js/JSNodeFilterCondition.h +++ b/WebCore/bindings/js/JSNodeFilterCondition.h @@ -30,18 +30,18 @@ namespace WebCore { class JSNodeFilterCondition : public NodeFilterCondition { public: - static PassRefPtr<JSNodeFilterCondition> create(JSC::JSValuePtr filter) + static PassRefPtr<JSNodeFilterCondition> create(JSC::JSValue filter) { return adoptRef(new JSNodeFilterCondition(filter)); } private: - JSNodeFilterCondition(JSC::JSValuePtr filter); + JSNodeFilterCondition(JSC::JSValue filter); virtual short acceptNode(ScriptState*, Node*) const; virtual void mark(); - mutable JSC::JSValuePtr m_filter; + mutable JSC::JSValue m_filter; }; } // namespace WebCore diff --git a/WebCore/bindings/js/JSNodeFilterCustom.cpp b/WebCore/bindings/js/JSNodeFilterCustom.cpp index 61fd0e2..ecc12d5 100644 --- a/WebCore/bindings/js/JSNodeFilterCustom.cpp +++ b/WebCore/bindings/js/JSNodeFilterCustom.cpp @@ -41,12 +41,12 @@ void JSNodeFilter::mark() DOMObject::mark(); } -JSValuePtr JSNodeFilter::acceptNode(ExecState* exec, const ArgList& args) +JSValue JSNodeFilter::acceptNode(ExecState* exec, const ArgList& args) { - return jsNumber(exec, impl()->acceptNode(exec, toNode(args.at(exec, 0)))); + return jsNumber(exec, impl()->acceptNode(exec, toNode(args.at(0)))); } -PassRefPtr<NodeFilter> toNodeFilter(JSValuePtr value) +PassRefPtr<NodeFilter> toNodeFilter(JSValue value) { if (value.isObject(&JSNodeFilter::s_info)) return static_cast<JSNodeFilter*>(asObject(value))->impl(); diff --git a/WebCore/bindings/js/JSNodeIteratorCustom.cpp b/WebCore/bindings/js/JSNodeIteratorCustom.cpp index 6498a7c..8fff82e 100644 --- a/WebCore/bindings/js/JSNodeIteratorCustom.cpp +++ b/WebCore/bindings/js/JSNodeIteratorCustom.cpp @@ -37,7 +37,7 @@ void JSNodeIterator::mark() DOMObject::mark(); } -JSValuePtr JSNodeIterator::nextNode(ExecState* exec, const ArgList&) +JSValue JSNodeIterator::nextNode(ExecState* exec, const ArgList&) { ExceptionCode ec = 0; RefPtr<Node> node = impl()->nextNode(exec, ec); @@ -52,7 +52,7 @@ JSValuePtr JSNodeIterator::nextNode(ExecState* exec, const ArgList&) return toJS(exec, node.get()); } -JSValuePtr JSNodeIterator::previousNode(ExecState* exec, const ArgList&) +JSValue JSNodeIterator::previousNode(ExecState* exec, const ArgList&) { ExceptionCode ec = 0; RefPtr<Node> node = impl()->previousNode(exec, ec); diff --git a/WebCore/bindings/js/JSNodeListCustom.cpp b/WebCore/bindings/js/JSNodeListCustom.cpp index 386a756..2821d01 100644 --- a/WebCore/bindings/js/JSNodeListCustom.cpp +++ b/WebCore/bindings/js/JSNodeListCustom.cpp @@ -36,10 +36,10 @@ using namespace JSC; namespace WebCore { // Need to support call so that list(0) works. -static JSValuePtr callNodeList(ExecState* exec, JSObject* function, JSValuePtr, const ArgList& args) +static JSValue JSC_HOST_CALL callNodeList(ExecState* exec, JSObject* function, JSValue, const ArgList& args) { bool ok; - unsigned index = args.at(exec, 0).toString(exec).toUInt32(&ok); + unsigned index = args.at(0).toString(exec).toUInt32(&ok); if (!ok) return jsUndefined(); return toJS(exec, static_cast<JSNodeList*>(function)->impl()->item(index)); @@ -56,7 +56,7 @@ bool JSNodeList::canGetItemsForName(ExecState*, NodeList* impl, const Identifier return impl->itemWithName(propertyName); } -JSValuePtr JSNodeList::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSNodeList::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { JSNodeList* thisObj = static_cast<JSNodeList*>(asObject(slot.slotBase())); return toJS(exec, thisObj->impl()->itemWithName(propertyName)); diff --git a/WebCore/bindings/js/JSOptionConstructor.cpp b/WebCore/bindings/js/JSOptionConstructor.cpp index e1d5cfe..9e818ff 100644 --- a/WebCore/bindings/js/JSOptionConstructor.cpp +++ b/WebCore/bindings/js/JSOptionConstructor.cpp @@ -34,13 +34,14 @@ ASSERT_CLASS_FITS_IN_CELL(JSOptionConstructor); const ClassInfo JSOptionConstructor::s_info = { "OptionConstructor", 0, 0, 0 }; -JSOptionConstructor::JSOptionConstructor(ExecState* exec, ScriptExecutionContext* context) +JSOptionConstructor::JSOptionConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) : DOMObject(JSOptionConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) - , m_globalObject(toJSDOMGlobalObject(context)) + , m_globalObject(globalObject) { - ASSERT(context->isDocument()); + ASSERT(globalObject->scriptExecutionContext()); + ASSERT(globalObject->scriptExecutionContext()->isDocument()); - putDirect(exec->propertyNames().prototype, JSHTMLOptionElementPrototype::self(exec), None); + putDirect(exec->propertyNames().prototype, JSHTMLOptionElementPrototype::self(exec, exec->lexicalGlobalObject()), None); putDirect(exec->propertyNames().length, jsNumber(exec, 4), ReadOnly|DontDelete|DontEnum); } @@ -52,21 +53,23 @@ Document* JSOptionConstructor::document() const static JSObject* constructHTMLOptionElement(ExecState* exec, JSObject* constructor, const ArgList& args) { Document* document = static_cast<JSOptionConstructor*>(constructor)->document(); + if (!document) + return throwError(exec, ReferenceError, "Option constructor associated document is unavailable"); RefPtr<HTMLOptionElement> element = static_pointer_cast<HTMLOptionElement>(document->createElement(HTMLNames::optionTag, false)); ExceptionCode ec = 0; RefPtr<Text> text = document->createTextNode(""); - if (!args.at(exec, 0).isUndefined()) - text->setData(args.at(exec, 0).toString(exec), ec); + if (!args.at(0).isUndefined()) + text->setData(args.at(0).toString(exec), ec); if (ec == 0) element->appendChild(text.release(), ec); - if (ec == 0 && !args.at(exec, 1).isUndefined()) - element->setValue(args.at(exec, 1).toString(exec)); + if (ec == 0 && !args.at(1).isUndefined()) + element->setValue(args.at(1).toString(exec)); if (ec == 0) - element->setDefaultSelected(args.at(exec, 2).toBoolean(exec)); + element->setDefaultSelected(args.at(2).toBoolean(exec)); if (ec == 0) - element->setSelected(args.at(exec, 3).toBoolean(exec)); + element->setSelected(args.at(3).toBoolean(exec)); if (ec) { setDOMException(exec, ec); diff --git a/WebCore/bindings/js/JSOptionConstructor.h b/WebCore/bindings/js/JSOptionConstructor.h index 60f6873..3c87c28 100644 --- a/WebCore/bindings/js/JSOptionConstructor.h +++ b/WebCore/bindings/js/JSOptionConstructor.h @@ -28,7 +28,7 @@ namespace WebCore { class JSOptionConstructor : public DOMObject { public: - JSOptionConstructor(JSC::ExecState*, ScriptExecutionContext*); + JSOptionConstructor(JSC::ExecState*, JSDOMGlobalObject*); Document* document() const; static const JSC::ClassInfo s_info; diff --git a/WebCore/bindings/js/JSPluginArrayCustom.cpp b/WebCore/bindings/js/JSPluginArrayCustom.cpp index 5e82942..81d4295 100644 --- a/WebCore/bindings/js/JSPluginArrayCustom.cpp +++ b/WebCore/bindings/js/JSPluginArrayCustom.cpp @@ -33,7 +33,7 @@ bool JSPluginArray::canGetItemsForName(ExecState*, PluginArray* pluginArray, con return pluginArray->canGetItemsForName(propertyName); } -JSValuePtr JSPluginArray::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSPluginArray::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { JSPluginArray* thisObj = static_cast<JSPluginArray*>(asObject(slot.slotBase())); return toJS(exec, thisObj->impl()->namedItem(propertyName)); diff --git a/WebCore/bindings/js/JSPluginCustom.cpp b/WebCore/bindings/js/JSPluginCustom.cpp index 2cc3bae..555dd9e 100644 --- a/WebCore/bindings/js/JSPluginCustom.cpp +++ b/WebCore/bindings/js/JSPluginCustom.cpp @@ -32,7 +32,7 @@ bool JSPlugin::canGetItemsForName(ExecState*, Plugin* plugin, const Identifier& return plugin->canGetItemsForName(propertyName); } -JSValuePtr JSPlugin::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSPlugin::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { JSPlugin* thisObj = static_cast<JSPlugin*>(asObject(slot.slotBase())); return toJS(exec, thisObj->impl()->namedItem(propertyName)); diff --git a/WebCore/bindings/js/JSPluginElementFunctions.cpp b/WebCore/bindings/js/JSPluginElementFunctions.cpp index eeaa394..56b0eca 100644 --- a/WebCore/bindings/js/JSPluginElementFunctions.cpp +++ b/WebCore/bindings/js/JSPluginElementFunctions.cpp @@ -57,7 +57,7 @@ static RuntimeObjectImp* getRuntimeObject(ExecState* exec, Node* node) return instance->createRuntimeObject(exec); } -JSValuePtr runtimeObjectGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) +JSValue runtimeObjectGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) { JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(asObject(slot.slotBase())); HTMLElement* element = static_cast<HTMLElement*>(thisObj->impl()); @@ -65,7 +65,7 @@ JSValuePtr runtimeObjectGetter(ExecState* exec, const Identifier&, const Propert return runtimeObject ? runtimeObject : jsUndefined(); } -JSValuePtr runtimeObjectPropertyGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue runtimeObjectPropertyGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(asObject(slot.slotBase())); HTMLElement* element = static_cast<HTMLElement*>(thisObj->impl()); @@ -86,7 +86,7 @@ bool runtimeObjectCustomGetOwnPropertySlot(ExecState* exec, const Identifier& pr return true; } -bool runtimeObjectCustomPut(ExecState* exec, const Identifier& propertyName, JSValuePtr value, HTMLElement* element, PutPropertySlot& slot) +bool runtimeObjectCustomPut(ExecState* exec, const Identifier& propertyName, JSValue value, HTMLElement* element, PutPropertySlot& slot) { RuntimeObjectImp* runtimeObject = getRuntimeObject(exec, element); if (!runtimeObject) @@ -97,11 +97,11 @@ bool runtimeObjectCustomPut(ExecState* exec, const Identifier& propertyName, JSV return true; } -static JSValuePtr callPlugin(ExecState* exec, JSObject* function, JSValuePtr, const ArgList& args) +static JSValue JSC_HOST_CALL callPlugin(ExecState* exec, JSObject* function, JSValue, const ArgList& args) { Instance* instance = pluginInstance(static_cast<JSHTMLElement*>(function)->impl()); instance->begin(); - JSValuePtr result = instance->invokeDefaultMethod(exec, args); + JSValue result = instance->invokeDefaultMethod(exec, args); instance->end(); return result; } diff --git a/WebCore/bindings/js/JSPluginElementFunctions.h b/WebCore/bindings/js/JSPluginElementFunctions.h index a1a86c0..8c9dfa7 100644 --- a/WebCore/bindings/js/JSPluginElementFunctions.h +++ b/WebCore/bindings/js/JSPluginElementFunctions.h @@ -30,10 +30,10 @@ namespace WebCore { // Runtime object support code for JSHTMLAppletElement, JSHTMLEmbedElement and JSHTMLObjectElement. - JSC::JSValuePtr runtimeObjectGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); - JSC::JSValuePtr runtimeObjectPropertyGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); + JSC::JSValue runtimeObjectGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); + JSC::JSValue runtimeObjectPropertyGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); bool runtimeObjectCustomGetOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&, JSHTMLElement*); - bool runtimeObjectCustomPut(JSC::ExecState*, const JSC::Identifier&, JSC::JSValuePtr, HTMLElement*, JSC::PutPropertySlot&); + bool runtimeObjectCustomPut(JSC::ExecState*, const JSC::Identifier&, JSC::JSValue, HTMLElement*, JSC::PutPropertySlot&); JSC::CallType runtimeObjectGetCallData(HTMLElement*, JSC::CallData&); } // namespace WebCore diff --git a/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp b/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp index c3fc41f..ad1e556 100644 --- a/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp +++ b/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp @@ -36,7 +36,7 @@ ASSERT_CLASS_FITS_IN_CELL(JSQuarantinedObjectWrapper); const ClassInfo JSQuarantinedObjectWrapper::s_info = { "JSQuarantinedObjectWrapper", 0, 0, 0 }; -JSQuarantinedObjectWrapper* JSQuarantinedObjectWrapper::asWrapper(JSValuePtr value) +JSQuarantinedObjectWrapper* JSQuarantinedObjectWrapper::asWrapper(JSValue value) { if (!value.isObject()) return 0; @@ -49,9 +49,9 @@ JSQuarantinedObjectWrapper* JSQuarantinedObjectWrapper::asWrapper(JSValuePtr val return static_cast<JSQuarantinedObjectWrapper*>(object); } -JSValuePtr JSQuarantinedObjectWrapper::cachedValueGetter(ExecState*, const Identifier&, const PropertySlot& slot) +JSValue JSQuarantinedObjectWrapper::cachedValueGetter(ExecState*, const Identifier&, const PropertySlot& slot) { - JSValuePtr v = slot.slotBase(); + JSValue v = slot.slotBase(); ASSERT(v); return v; } @@ -87,7 +87,7 @@ void JSQuarantinedObjectWrapper::transferExceptionToExecState(ExecState* exec) c if (!unwrappedExecState()->hadException()) return; - JSValuePtr exception = unwrappedExecState()->exception(); + JSValue exception = unwrappedExecState()->exception(); unwrappedExecState()->clearException(); exec->setException(wrapOutgoingValue(unwrappedExecState(), exception)); } @@ -112,7 +112,7 @@ bool JSQuarantinedObjectWrapper::getOwnPropertySlot(ExecState* exec, const Ident PropertySlot unwrappedSlot(m_unwrappedObject); bool result = m_unwrappedObject->getOwnPropertySlot(unwrappedExecState(), identifier, unwrappedSlot); if (result) { - JSValuePtr unwrappedValue = unwrappedSlot.getValue(unwrappedExecState(), identifier); + JSValue unwrappedValue = unwrappedSlot.getValue(unwrappedExecState(), identifier); slot.setCustom(wrapOutgoingValue(unwrappedExecState(), unwrappedValue), cachedValueGetter); } @@ -131,7 +131,7 @@ bool JSQuarantinedObjectWrapper::getOwnPropertySlot(ExecState* exec, unsigned id PropertySlot unwrappedSlot(m_unwrappedObject); bool result = m_unwrappedObject->getOwnPropertySlot(unwrappedExecState(), identifier, unwrappedSlot); if (result) { - JSValuePtr unwrappedValue = unwrappedSlot.getValue(unwrappedExecState(), identifier); + JSValue unwrappedValue = unwrappedSlot.getValue(unwrappedExecState(), identifier); slot.setCustom(wrapOutgoingValue(unwrappedExecState(), unwrappedValue), cachedValueGetter); } @@ -140,7 +140,7 @@ bool JSQuarantinedObjectWrapper::getOwnPropertySlot(ExecState* exec, unsigned id return result; } -void JSQuarantinedObjectWrapper::put(ExecState* exec, const Identifier& identifier, JSValuePtr value, PutPropertySlot& slot) +void JSQuarantinedObjectWrapper::put(ExecState* exec, const Identifier& identifier, JSValue value, PutPropertySlot& slot) { if (!allowsSetProperty()) return; @@ -150,7 +150,7 @@ void JSQuarantinedObjectWrapper::put(ExecState* exec, const Identifier& identifi transferExceptionToExecState(exec); } -void JSQuarantinedObjectWrapper::put(ExecState* exec, unsigned identifier, JSValuePtr value) +void JSQuarantinedObjectWrapper::put(ExecState* exec, unsigned identifier, JSValue value) { if (!allowsSetProperty()) return; @@ -188,9 +188,9 @@ JSObject* JSQuarantinedObjectWrapper::construct(ExecState* exec, JSObject* const { JSQuarantinedObjectWrapper* wrapper = static_cast<JSQuarantinedObjectWrapper*>(constructor); - ArgList preparedArgs; + MarkedArgumentBuffer preparedArgs; for (size_t i = 0; i < args.size(); ++i) - preparedArgs.append(wrapper->prepareIncomingValue(exec, args.at(exec, i))); + preparedArgs.append(wrapper->prepareIncomingValue(exec, args.at(i))); // FIXME: Would be nice to find a way to reuse the result of m_unwrappedObject->getConstructData // from when we called it in JSQuarantinedObjectWrapper::getConstructData. @@ -198,9 +198,9 @@ JSObject* JSQuarantinedObjectWrapper::construct(ExecState* exec, JSObject* const ConstructType unwrappedConstructType = wrapper->m_unwrappedObject->getConstructData(unwrappedConstructData); ASSERT(unwrappedConstructType != ConstructTypeNone); - JSValuePtr unwrappedResult = JSC::construct(wrapper->unwrappedExecState(), wrapper->m_unwrappedObject, unwrappedConstructType, unwrappedConstructData, preparedArgs); + JSValue unwrappedResult = JSC::construct(wrapper->unwrappedExecState(), wrapper->m_unwrappedObject, unwrappedConstructType, unwrappedConstructData, preparedArgs); - JSValuePtr resultValue = wrapper->wrapOutgoingValue(wrapper->unwrappedExecState(), unwrappedResult); + JSValue resultValue = wrapper->wrapOutgoingValue(wrapper->unwrappedExecState(), unwrappedResult); ASSERT(resultValue.isObject()); JSObject* result = asObject(resultValue); @@ -220,7 +220,7 @@ ConstructType JSQuarantinedObjectWrapper::getConstructData(ConstructData& constr return ConstructTypeHost; } -bool JSQuarantinedObjectWrapper::hasInstance(ExecState* exec, JSValuePtr value, JSValuePtr proto) +bool JSQuarantinedObjectWrapper::hasInstance(ExecState* exec, JSValue value, JSValue proto) { if (!allowsHasInstance()) return false; @@ -232,15 +232,15 @@ bool JSQuarantinedObjectWrapper::hasInstance(ExecState* exec, JSValuePtr value, return result; } -JSValuePtr JSQuarantinedObjectWrapper::call(ExecState* exec, JSObject* function, JSValuePtr thisValue, const ArgList& args) +JSValue JSQuarantinedObjectWrapper::call(ExecState* exec, JSObject* function, JSValue thisValue, const ArgList& args) { JSQuarantinedObjectWrapper* wrapper = static_cast<JSQuarantinedObjectWrapper*>(function); - JSValuePtr preparedThisValue = wrapper->prepareIncomingValue(exec, thisValue); + JSValue preparedThisValue = wrapper->prepareIncomingValue(exec, thisValue); - ArgList preparedArgs; + MarkedArgumentBuffer preparedArgs; for (size_t i = 0; i < args.size(); ++i) - preparedArgs.append(wrapper->prepareIncomingValue(exec, args.at(exec, i))); + preparedArgs.append(wrapper->prepareIncomingValue(exec, args.at(i))); // FIXME: Would be nice to find a way to reuse the result of m_unwrappedObject->getCallData // from when we called it in JSQuarantinedObjectWrapper::getCallData. @@ -248,9 +248,9 @@ JSValuePtr JSQuarantinedObjectWrapper::call(ExecState* exec, JSObject* function, CallType unwrappedCallType = wrapper->m_unwrappedObject->getCallData(unwrappedCallData); ASSERT(unwrappedCallType != CallTypeNone); - JSValuePtr unwrappedResult = JSC::call(wrapper->unwrappedExecState(), wrapper->m_unwrappedObject, unwrappedCallType, unwrappedCallData, preparedThisValue, preparedArgs); + JSValue unwrappedResult = JSC::call(wrapper->unwrappedExecState(), wrapper->m_unwrappedObject, unwrappedCallType, unwrappedCallData, preparedThisValue, preparedArgs); - JSValuePtr result = wrapper->wrapOutgoingValue(wrapper->unwrappedExecState(), unwrappedResult); + JSValue result = wrapper->wrapOutgoingValue(wrapper->unwrappedExecState(), unwrappedResult); wrapper->transferExceptionToExecState(exec); diff --git a/WebCore/bindings/js/JSQuarantinedObjectWrapper.h b/WebCore/bindings/js/JSQuarantinedObjectWrapper.h index d66dc46..bf8fddb 100644 --- a/WebCore/bindings/js/JSQuarantinedObjectWrapper.h +++ b/WebCore/bindings/js/JSQuarantinedObjectWrapper.h @@ -32,7 +32,7 @@ namespace WebCore { class JSQuarantinedObjectWrapper : public JSC::JSObject { public: - static JSQuarantinedObjectWrapper* asWrapper(JSC::JSValuePtr); + static JSQuarantinedObjectWrapper* asWrapper(JSC::JSValue); virtual ~JSQuarantinedObjectWrapper(); @@ -45,7 +45,7 @@ namespace WebCore { static const JSC::ClassInfo s_info; - static PassRefPtr<JSC::Structure> createStructure(JSC::JSValuePtr proto) + static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue proto) { return JSC::Structure::create(proto, JSC::TypeInfo(JSC::ObjectType, JSC::ImplementsHasInstance | JSC::OverridesHasInstance)); } @@ -59,8 +59,8 @@ namespace WebCore { virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&); virtual bool getOwnPropertySlot(JSC::ExecState*, unsigned, JSC::PropertySlot&); - virtual void put(JSC::ExecState*, const JSC::Identifier&, JSC::JSValuePtr, JSC::PutPropertySlot&); - virtual void put(JSC::ExecState*, unsigned, JSC::JSValuePtr); + virtual void put(JSC::ExecState*, const JSC::Identifier&, JSC::JSValue, JSC::PutPropertySlot&); + virtual void put(JSC::ExecState*, unsigned, JSC::JSValue); virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier&); virtual bool deleteProperty(JSC::ExecState*, unsigned); @@ -68,7 +68,7 @@ namespace WebCore { virtual JSC::CallType getCallData(JSC::CallData&); virtual JSC::ConstructType getConstructData(JSC::ConstructData&); - virtual bool hasInstance(JSC::ExecState*, JSC::JSValuePtr, JSC::JSValuePtr proto); + virtual bool hasInstance(JSC::ExecState*, JSC::JSValue, JSC::JSValue proto); virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&); @@ -82,14 +82,14 @@ namespace WebCore { virtual bool allowsCallAsFunction() const { return false; } virtual bool allowsGetPropertyNames() const { return false; } - virtual JSC::JSValuePtr prepareIncomingValue(JSC::ExecState* unwrappedExec, JSC::JSValuePtr unwrappedValue) const = 0; - virtual JSC::JSValuePtr wrapOutgoingValue(JSC::ExecState* unwrappedExec, JSC::JSValuePtr unwrappedValue) const = 0; + virtual JSC::JSValue prepareIncomingValue(JSC::ExecState* unwrappedExec, JSC::JSValue unwrappedValue) const = 0; + virtual JSC::JSValue wrapOutgoingValue(JSC::ExecState* unwrappedExec, JSC::JSValue unwrappedValue) const = 0; - static JSC::JSValuePtr cachedValueGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); + static JSC::JSValue cachedValueGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); void transferExceptionToExecState(JSC::ExecState*) const; - static JSC::JSValuePtr call(JSC::ExecState*, JSC::JSObject* function, JSC::JSValuePtr thisValue, const JSC::ArgList&); + static JSC::JSValue JSC_HOST_CALL call(JSC::ExecState*, JSC::JSObject* function, JSC::JSValue thisValue, const JSC::ArgList&); static JSC::JSObject* construct(JSC::ExecState*, JSC::JSObject*, const JSC::ArgList&); JSC::JSGlobalObject* m_unwrappedGlobalObject; diff --git a/WebCore/bindings/js/JSRGBColor.cpp b/WebCore/bindings/js/JSRGBColor.cpp index 90f8037..f7c87e2 100644 --- a/WebCore/bindings/js/JSRGBColor.cpp +++ b/WebCore/bindings/js/JSRGBColor.cpp @@ -28,9 +28,9 @@ using namespace JSC; -static JSValuePtr jsRGBColorRed(ExecState*, const Identifier&, const PropertySlot&); -static JSValuePtr jsRGBColorGreen(ExecState*, const Identifier&, const PropertySlot&); -static JSValuePtr jsRGBColorBlue(ExecState*, const Identifier&, const PropertySlot&); +static JSValue jsRGBColorRed(ExecState*, const Identifier&, const PropertySlot&); +static JSValue jsRGBColorGreen(ExecState*, const Identifier&, const PropertySlot&); +static JSValue jsRGBColorBlue(ExecState*, const Identifier&, const PropertySlot&); /* @begin JSRGBColorTable @@ -59,7 +59,7 @@ bool JSRGBColor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN return getStaticValueSlot<JSRGBColor, DOMObject>(exec, &JSRGBColorTable, this, propertyName, slot); } -JSValuePtr getJSRGBColor(ExecState* exec, unsigned color) +JSValue getJSRGBColor(ExecState* exec, unsigned color) { return new (exec) JSRGBColor(exec, color); } @@ -68,17 +68,17 @@ JSValuePtr getJSRGBColor(ExecState* exec, unsigned color) using namespace WebCore; -JSValuePtr jsRGBColorRed(ExecState* exec, const Identifier&, const PropertySlot& slot) +JSValue jsRGBColorRed(ExecState* exec, const Identifier&, const PropertySlot& slot) { return toJS(exec, CSSPrimitiveValue::create((static_cast<JSRGBColor*>(asObject(slot.slotBase()))->impl() >> 16) & 0xFF, CSSPrimitiveValue::CSS_NUMBER)); } -JSValuePtr jsRGBColorGreen(ExecState* exec, const Identifier&, const PropertySlot& slot) +JSValue jsRGBColorGreen(ExecState* exec, const Identifier&, const PropertySlot& slot) { return toJS(exec, CSSPrimitiveValue::create((static_cast<JSRGBColor*>(asObject(slot.slotBase()))->impl() >> 8) & 0xFF, CSSPrimitiveValue::CSS_NUMBER)); } -JSValuePtr jsRGBColorBlue(ExecState* exec, const Identifier&, const PropertySlot& slot) +JSValue jsRGBColorBlue(ExecState* exec, const Identifier&, const PropertySlot& slot) { return toJS(exec, CSSPrimitiveValue::create(static_cast<JSRGBColor*>(asObject(slot.slotBase()))->impl() & 0xFF, CSSPrimitiveValue::CSS_NUMBER)); } diff --git a/WebCore/bindings/js/JSRGBColor.h b/WebCore/bindings/js/JSRGBColor.h index d5acff3..cc2870f 100644 --- a/WebCore/bindings/js/JSRGBColor.h +++ b/WebCore/bindings/js/JSRGBColor.h @@ -38,12 +38,12 @@ namespace WebCore { unsigned impl() const { return m_color; } - static JSC::ObjectPrototype* createPrototype(JSC::ExecState* exec) + static JSC::ObjectPrototype* createPrototype(JSC::ExecState*, JSC::JSGlobalObject* globalObject) { - return exec->lexicalGlobalObject()->objectPrototype(); + return globalObject->objectPrototype(); } - static PassRefPtr<JSC::Structure> createStructure(JSC::JSValuePtr prototype) + static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) { return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType)); } @@ -52,7 +52,7 @@ namespace WebCore { unsigned m_color; }; - JSC::JSValuePtr getJSRGBColor(JSC::ExecState*, unsigned color); + JSC::JSValue getJSRGBColor(JSC::ExecState*, unsigned color); } // namespace WebCore diff --git a/WebCore/bindings/js/JSSQLResultSetRowListCustom.cpp b/WebCore/bindings/js/JSSQLResultSetRowListCustom.cpp index 53696d4..f40956e 100644 --- a/WebCore/bindings/js/JSSQLResultSetRowListCustom.cpp +++ b/WebCore/bindings/js/JSSQLResultSetRowListCustom.cpp @@ -39,10 +39,10 @@ using namespace JSC; namespace WebCore { -JSValuePtr JSSQLResultSetRowList::item(ExecState* exec, const ArgList& args) +JSValue JSSQLResultSetRowList::item(ExecState* exec, const ArgList& args) { bool indexOk; - int index = args.at(exec, 0).toInt32(exec, indexOk); + int index = args.at(0).toInt32(exec, indexOk); if (!indexOk) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); @@ -58,7 +58,7 @@ JSValuePtr JSSQLResultSetRowList::item(ExecState* exec, const ArgList& args) unsigned valuesIndex = index * numColumns; for (unsigned i = 0; i < numColumns; i++) { const SQLValue& value = m_impl->values()[valuesIndex + i]; - JSValuePtr jsValue = noValue(); + JSValue jsValue; switch (value.type()) { case SQLValue::StringValue: diff --git a/WebCore/bindings/js/JSSQLTransactionCustom.cpp b/WebCore/bindings/js/JSSQLTransactionCustom.cpp index 064ab15..30d59aa 100644 --- a/WebCore/bindings/js/JSSQLTransactionCustom.cpp +++ b/WebCore/bindings/js/JSSQLTransactionCustom.cpp @@ -42,22 +42,22 @@ using namespace JSC; namespace WebCore { -JSValuePtr JSSQLTransaction::executeSql(ExecState* exec, const ArgList& args) +JSValue JSSQLTransaction::executeSql(ExecState* exec, const ArgList& args) { - String sqlStatement = args.at(exec, 0).toString(exec); + String sqlStatement = args.at(0).toString(exec); if (exec->hadException()) return jsUndefined(); // Now assemble the list of SQL arguments Vector<SQLValue> sqlValues; - if (!args.at(exec, 1).isUndefinedOrNull()) { - JSObject* object = args.at(exec, 1).getObject(); + if (!args.at(1).isUndefinedOrNull()) { + JSObject* object = args.at(1).getObject(); if (!object) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); } - JSValuePtr lengthValue = object->get(exec, exec->propertyNames().length); + JSValue lengthValue = object->get(exec, exec->propertyNames().length); if (exec->hadException()) return jsUndefined(); unsigned length = lengthValue.toUInt32(exec); @@ -65,7 +65,7 @@ JSValuePtr JSSQLTransaction::executeSql(ExecState* exec, const ArgList& args) return jsUndefined(); for (unsigned i = 0 ; i < length; ++i) { - JSValuePtr value = object->get(exec, i); + JSValue value = object->get(exec, i); if (exec->hadException()) return jsUndefined(); @@ -83,8 +83,8 @@ JSValuePtr JSSQLTransaction::executeSql(ExecState* exec, const ArgList& args) } RefPtr<SQLStatementCallback> callback; - if (!args.at(exec, 2).isUndefinedOrNull()) { - JSObject* object = args.at(exec, 2).getObject(); + if (!args.at(2).isUndefinedOrNull()) { + JSObject* object = args.at(2).getObject(); if (!object) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); @@ -95,8 +95,8 @@ JSValuePtr JSSQLTransaction::executeSql(ExecState* exec, const ArgList& args) } RefPtr<SQLStatementErrorCallback> errorCallback; - if (!args.at(exec, 3).isUndefinedOrNull()) { - JSObject* object = args.at(exec, 3).getObject(); + if (!args.at(3).isUndefinedOrNull()) { + JSObject* object = args.at(3).getObject(); if (!object) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); diff --git a/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp b/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp index 56ceb7c..2922740 100644 --- a/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp +++ b/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp @@ -26,36 +26,47 @@ #include "config.h" #if ENABLE(SVG) -#include "SVGElementInstance.h" #include "JSSVGElementInstance.h" -#include "JSEventListener.h" #include "JSDOMWindow.h" +#include "JSEventListener.h" +#include "JSSVGElement.h" +#include "SVGElementInstance.h" using namespace JSC; namespace WebCore { -JSValuePtr JSSVGElementInstance::addEventListener(ExecState* exec, const ArgList& args) +void JSSVGElementInstance::mark() +{ + DOMObject::mark(); + + // Mark the wrapper for our corresponding element, so it can mark its event handlers. + JSNode* correspondingWrapper = getCachedDOMNodeWrapper(impl()->correspondingElement()->document(), impl()->correspondingElement()); + if (correspondingWrapper && !correspondingWrapper->marked()) + correspondingWrapper->mark(); +} + +JSValue JSSVGElementInstance::addEventListener(ExecState* exec, const ArgList& args) { JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - if (RefPtr<JSProtectedEventListener> listener = globalObject->findOrCreateJSProtectedEventListener(exec, args.at(exec, 1))) - impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec)); + if (RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(args.at(1))) + impl()->addEventListener(args.at(0).toString(exec), listener.release(), args.at(2).toBoolean(exec)); return jsUndefined(); } -JSValuePtr JSSVGElementInstance::removeEventListener(ExecState* exec, const ArgList& args) +JSValue JSSVGElementInstance::removeEventListener(ExecState* exec, const ArgList& args) { JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - if (JSProtectedEventListener* listener = globalObject->findJSProtectedEventListener(args.at(exec, 1))) - impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec)); + if (JSEventListener* listener = globalObject->findJSEventListener(args.at(1))) + impl()->removeEventListener(args.at(0).toString(exec), listener, args.at(2).toBoolean(exec)); return jsUndefined(); } @@ -64,6 +75,17 @@ void JSSVGElementInstance::pushEventHandlerScope(ExecState*, ScopeChain&) const { } +JSC::JSValue toJS(JSC::ExecState* exec, SVGElementInstance* object) +{ + JSValue result = getDOMObjectWrapper<JSSVGElementInstance>(exec, object); + + // Ensure that our corresponding element has a JavaScript wrapper to keep its event handlers alive. + if (object) + toJS(exec, object->correspondingElement()); + + return result; } -#endif +} // namespace WebCore + +#endif // ENABLE(SVG) diff --git a/WebCore/bindings/js/JSSVGLengthCustom.cpp b/WebCore/bindings/js/JSSVGLengthCustom.cpp index edba220..bad52ae 100644 --- a/WebCore/bindings/js/JSSVGLengthCustom.cpp +++ b/WebCore/bindings/js/JSSVGLengthCustom.cpp @@ -26,18 +26,18 @@ using namespace JSC; namespace WebCore { -JSValuePtr JSSVGLength::value(ExecState* exec) const +JSValue JSSVGLength::value(ExecState* exec) const { SVGLength imp(*impl()); return jsNumber(exec, imp.value(context())); } -JSValuePtr JSSVGLength::convertToSpecifiedUnits(ExecState* exec, const ArgList& args) +JSValue JSSVGLength::convertToSpecifiedUnits(ExecState* exec, const ArgList& args) { JSSVGPODTypeWrapper<SVGLength>* wrapper = impl(); SVGLength imp(*wrapper); - imp.convertToSpecifiedUnits(args.at(exec, 0).toInt32(exec), context()); + imp.convertToSpecifiedUnits(args.at(0).toInt32(exec), context()); wrapper->commitChange(imp, context()); return jsUndefined(); diff --git a/WebCore/bindings/js/JSSVGMatrixCustom.cpp b/WebCore/bindings/js/JSSVGMatrixCustom.cpp index 0dd086d..fc1e266 100644 --- a/WebCore/bindings/js/JSSVGMatrixCustom.cpp +++ b/WebCore/bindings/js/JSSVGMatrixCustom.cpp @@ -29,10 +29,10 @@ using namespace JSC; namespace WebCore { -JSValuePtr JSSVGMatrix::inverse(ExecState* exec, const ArgList&) +JSValue JSSVGMatrix::inverse(ExecState* exec, const ArgList&) { TransformationMatrix imp(*impl()); - JSC::JSValuePtr result = toJS(exec, JSSVGStaticPODTypeWrapper<TransformationMatrix>::create(imp.inverse()).get(), m_context.get()); + JSC::JSValue result = toJS(exec, JSSVGStaticPODTypeWrapper<TransformationMatrix>::create(imp.inverse()).get(), m_context.get()); if (!imp.isInvertible()) setDOMException(exec, SVGException::SVG_MATRIX_NOT_INVERTABLE); @@ -40,14 +40,14 @@ JSValuePtr JSSVGMatrix::inverse(ExecState* exec, const ArgList&) return result; } -JSValuePtr JSSVGMatrix::rotateFromVector(ExecState* exec, const ArgList& args) +JSValue JSSVGMatrix::rotateFromVector(ExecState* exec, const ArgList& args) { TransformationMatrix imp(*impl()); - float x = args.at(exec, 0).toFloat(exec); - float y = args.at(exec, 1).toFloat(exec); + float x = args.at(0).toFloat(exec); + float y = args.at(1).toFloat(exec); - JSC::JSValuePtr result = toJS(exec, JSSVGStaticPODTypeWrapper<TransformationMatrix>::create(imp.rotateFromVector(x, y)).get(), m_context.get()); + JSC::JSValue result = toJS(exec, JSSVGStaticPODTypeWrapper<TransformationMatrix>::create(imp.rotateFromVector(x, y)).get(), m_context.get()); if (x == 0.0 || y == 0.0) setDOMException(exec, SVGException::SVG_INVALID_VALUE_ERR); diff --git a/WebCore/bindings/js/JSSVGPathSegCustom.cpp b/WebCore/bindings/js/JSSVGPathSegCustom.cpp index b7490e7..cb4687c 100644 --- a/WebCore/bindings/js/JSSVGPathSegCustom.cpp +++ b/WebCore/bindings/js/JSSVGPathSegCustom.cpp @@ -59,7 +59,7 @@ using namespace JSC; namespace WebCore { -JSValuePtr toJS(ExecState* exec, SVGPathSeg* object, SVGElement* context) +JSValue toJS(ExecState* exec, SVGPathSeg* object, SVGElement* context) { if (!object) return jsNull(); diff --git a/WebCore/bindings/js/JSSVGPathSegListCustom.cpp b/WebCore/bindings/js/JSSVGPathSegListCustom.cpp index 69fb3b5..b6fc116 100644 --- a/WebCore/bindings/js/JSSVGPathSegListCustom.cpp +++ b/WebCore/bindings/js/JSSVGPathSegListCustom.cpp @@ -35,7 +35,7 @@ using namespace JSC; namespace WebCore { -JSValuePtr JSSVGPathSegList::clear(ExecState* exec, const ArgList&) +JSValue JSSVGPathSegList::clear(ExecState* exec, const ArgList&) { ExceptionCode ec = 0; @@ -48,28 +48,28 @@ JSValuePtr JSSVGPathSegList::clear(ExecState* exec, const ArgList&) return jsUndefined(); } -JSValuePtr JSSVGPathSegList::initialize(ExecState* exec, const ArgList& args) +JSValue JSSVGPathSegList::initialize(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; - SVGPathSeg* newItem = toSVGPathSeg(args.at(exec, 0)); + SVGPathSeg* newItem = toSVGPathSeg(args.at(0)); SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); SVGPathSeg* obj = WTF::getPtr(imp->initialize(newItem, ec)); - JSC::JSValuePtr result = toJS(exec, obj, m_context.get()); + JSC::JSValue result = toJS(exec, obj, m_context.get()); setDOMException(exec, ec); m_context->svgAttributeChanged(imp->associatedAttributeName()); return result; } -JSValuePtr JSSVGPathSegList::getItem(ExecState* exec, const ArgList& args) +JSValue JSSVGPathSegList::getItem(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; bool indexOk; - unsigned index = args.at(exec, 0).toInt32(exec, indexOk); + unsigned index = args.at(0).toInt32(exec, indexOk); if (!indexOk) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); @@ -78,18 +78,18 @@ JSValuePtr JSSVGPathSegList::getItem(ExecState* exec, const ArgList& args) SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); SVGPathSeg* obj = WTF::getPtr(imp->getItem(index, ec)); - JSC::JSValuePtr result = toJS(exec, obj, m_context.get()); + JSC::JSValue result = toJS(exec, obj, m_context.get()); setDOMException(exec, ec); return result; } -JSValuePtr JSSVGPathSegList::insertItemBefore(ExecState* exec, const ArgList& args) +JSValue JSSVGPathSegList::insertItemBefore(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; - SVGPathSeg* newItem = toSVGPathSeg(args.at(exec, 0)); + SVGPathSeg* newItem = toSVGPathSeg(args.at(0)); bool indexOk; - unsigned index = args.at(exec, 1).toInt32(exec, indexOk); + unsigned index = args.at(1).toInt32(exec, indexOk); if (!indexOk) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); @@ -97,20 +97,20 @@ JSValuePtr JSSVGPathSegList::insertItemBefore(ExecState* exec, const ArgList& ar SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); - JSC::JSValuePtr result = toJS(exec, WTF::getPtr(imp->insertItemBefore(newItem, index, ec)), m_context.get()); + JSC::JSValue result = toJS(exec, WTF::getPtr(imp->insertItemBefore(newItem, index, ec)), m_context.get()); setDOMException(exec, ec); m_context->svgAttributeChanged(imp->associatedAttributeName()); return result; } -JSValuePtr JSSVGPathSegList::replaceItem(ExecState* exec, const ArgList& args) +JSValue JSSVGPathSegList::replaceItem(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; - SVGPathSeg* newItem = toSVGPathSeg(args.at(exec, 0)); + SVGPathSeg* newItem = toSVGPathSeg(args.at(0)); bool indexOk; - unsigned index = args.at(exec, 1).toInt32(exec, indexOk); + unsigned index = args.at(1).toInt32(exec, indexOk); if (!indexOk) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); @@ -118,19 +118,19 @@ JSValuePtr JSSVGPathSegList::replaceItem(ExecState* exec, const ArgList& args) SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); - JSC::JSValuePtr result = toJS(exec, WTF::getPtr(imp->replaceItem(newItem, index, ec)), m_context.get()); + JSC::JSValue result = toJS(exec, WTF::getPtr(imp->replaceItem(newItem, index, ec)), m_context.get()); setDOMException(exec, ec); m_context->svgAttributeChanged(imp->associatedAttributeName()); return result; } -JSValuePtr JSSVGPathSegList::removeItem(ExecState* exec, const ArgList& args) +JSValue JSSVGPathSegList::removeItem(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; bool indexOk; - unsigned index = args.at(exec, 0).toInt32(exec, indexOk); + unsigned index = args.at(0).toInt32(exec, indexOk); if (!indexOk) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); @@ -140,21 +140,21 @@ JSValuePtr JSSVGPathSegList::removeItem(ExecState* exec, const ArgList& args) RefPtr<SVGPathSeg> obj(imp->removeItem(index, ec)); - JSC::JSValuePtr result = toJS(exec, obj.get(), m_context.get()); + JSC::JSValue result = toJS(exec, obj.get(), m_context.get()); setDOMException(exec, ec); m_context->svgAttributeChanged(imp->associatedAttributeName()); return result; } -JSValuePtr JSSVGPathSegList::appendItem(ExecState* exec, const ArgList& args) +JSValue JSSVGPathSegList::appendItem(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; - SVGPathSeg* newItem = toSVGPathSeg(args.at(exec, 0)); + SVGPathSeg* newItem = toSVGPathSeg(args.at(0)); SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl()); - JSC::JSValuePtr result = toJS(exec, WTF::getPtr(imp->appendItem(newItem, ec)), m_context.get()); + JSC::JSValue result = toJS(exec, WTF::getPtr(imp->appendItem(newItem, ec)), m_context.get()); setDOMException(exec, ec); m_context->svgAttributeChanged(imp->associatedAttributeName()); diff --git a/WebCore/bindings/js/JSSVGPointListCustom.cpp b/WebCore/bindings/js/JSSVGPointListCustom.cpp index 580b56f..a18c2a2 100644 --- a/WebCore/bindings/js/JSSVGPointListCustom.cpp +++ b/WebCore/bindings/js/JSSVGPointListCustom.cpp @@ -33,7 +33,7 @@ namespace WebCore { typedef SVGPODListItem<FloatPoint> PODListItem; typedef SVGList<RefPtr<PODListItem> > SVGPointListBase; -static JSValuePtr finishGetter(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGPointList* list, PassRefPtr<PODListItem > item) +static JSValue finishGetter(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGPointList* list, PassRefPtr<PODListItem > item) { if (ec) { setDOMException(exec, ec); @@ -42,7 +42,7 @@ static JSValuePtr finishGetter(ExecState* exec, ExceptionCode& ec, SVGElement* c return toJS(exec, JSSVGPODTypeWrapperCreatorForList<FloatPoint>::create(item.get(), list->associatedAttributeName()).get(), context); } -static JSValuePtr finishSetter(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGPointList* list, PassRefPtr<PODListItem > item) +static JSValue finishSetter(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGPointList* list, PassRefPtr<PODListItem > item) { if (ec) { setDOMException(exec, ec); @@ -53,7 +53,7 @@ static JSValuePtr finishSetter(ExecState* exec, ExceptionCode& ec, SVGElement* c return toJS(exec, JSSVGPODTypeWrapperCreatorForList<FloatPoint>::create(item.get(), attributeName).get(), context); } -static JSValuePtr finishSetterReadOnlyResult(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGPointList* list, PassRefPtr<PODListItem> item) +static JSValue finishSetterReadOnlyResult(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGPointList* list, PassRefPtr<PODListItem> item) { if (ec) { setDOMException(exec, ec); @@ -63,7 +63,7 @@ static JSValuePtr finishSetterReadOnlyResult(ExecState* exec, ExceptionCode& ec, return toJS(exec, JSSVGStaticPODTypeWrapper<FloatPoint>::create(*item).get(), context); } -JSValuePtr JSSVGPointList::clear(ExecState* exec, const ArgList&) +JSValue JSSVGPointList::clear(ExecState* exec, const ArgList&) { ExceptionCode ec = 0; impl()->clear(ec); @@ -72,18 +72,18 @@ JSValuePtr JSSVGPointList::clear(ExecState* exec, const ArgList&) return jsUndefined(); } -JSValuePtr JSSVGPointList::initialize(ExecState* exec, const ArgList& args) +JSValue JSSVGPointList::initialize(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; SVGPointListBase* listImp = impl(); return finishSetter(exec, ec, context(), impl(), - listImp->initialize(PODListItem::copy(toSVGPoint(args.at(exec, 0))), ec)); + listImp->initialize(PODListItem::copy(toSVGPoint(args.at(0))), ec)); } -JSValuePtr JSSVGPointList::getItem(ExecState* exec, const ArgList& args) +JSValue JSSVGPointList::getItem(ExecState* exec, const ArgList& args) { bool indexOk; - unsigned index = args.at(exec, 0).toUInt32(exec, indexOk); + unsigned index = args.at(0).toUInt32(exec, indexOk); if (!indexOk) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); @@ -95,10 +95,10 @@ JSValuePtr JSSVGPointList::getItem(ExecState* exec, const ArgList& args) listImp->getItem(index, ec)); } -JSValuePtr JSSVGPointList::insertItemBefore(ExecState* exec, const ArgList& args) +JSValue JSSVGPointList::insertItemBefore(ExecState* exec, const ArgList& args) { bool indexOk; - unsigned index = args.at(exec, 1).toUInt32(exec, indexOk); + unsigned index = args.at(1).toUInt32(exec, indexOk); if (!indexOk) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); @@ -107,13 +107,13 @@ JSValuePtr JSSVGPointList::insertItemBefore(ExecState* exec, const ArgList& args ExceptionCode ec = 0; SVGPointListBase* listImp = impl(); return finishSetter(exec, ec, context(), impl(), - listImp->insertItemBefore(PODListItem::copy(toSVGPoint(args.at(exec, 0))), index, ec)); + listImp->insertItemBefore(PODListItem::copy(toSVGPoint(args.at(0))), index, ec)); } -JSValuePtr JSSVGPointList::replaceItem(ExecState* exec, const ArgList& args) +JSValue JSSVGPointList::replaceItem(ExecState* exec, const ArgList& args) { bool indexOk; - unsigned index = args.at(exec, 1).toInt32(exec, indexOk); + unsigned index = args.at(1).toInt32(exec, indexOk); if (!indexOk) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); @@ -122,13 +122,13 @@ JSValuePtr JSSVGPointList::replaceItem(ExecState* exec, const ArgList& args) ExceptionCode ec = 0; SVGPointListBase* listImp = impl(); return finishSetter(exec, ec, context(), impl(), - listImp->replaceItem(PODListItem::copy(toSVGPoint(args.at(exec, 0))), index, ec)); + listImp->replaceItem(PODListItem::copy(toSVGPoint(args.at(0))), index, ec)); } -JSValuePtr JSSVGPointList::removeItem(ExecState* exec, const ArgList& args) +JSValue JSSVGPointList::removeItem(ExecState* exec, const ArgList& args) { bool indexOk; - unsigned index = args.at(exec, 0).toInt32(exec, indexOk); + unsigned index = args.at(0).toInt32(exec, indexOk); if (!indexOk) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); @@ -140,12 +140,12 @@ JSValuePtr JSSVGPointList::removeItem(ExecState* exec, const ArgList& args) listImp->removeItem(index, ec)); } -JSValuePtr JSSVGPointList::appendItem(ExecState* exec, const ArgList& args) +JSValue JSSVGPointList::appendItem(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; SVGPointListBase* listImp = impl(); return finishSetter(exec, ec, context(), impl(), - listImp->appendItem(PODListItem::copy(toSVGPoint(args.at(exec, 0))), ec)); + listImp->appendItem(PODListItem::copy(toSVGPoint(args.at(0))), ec)); } } diff --git a/WebCore/bindings/js/JSSVGTransformListCustom.cpp b/WebCore/bindings/js/JSSVGTransformListCustom.cpp index 3bdb2e0..58b25ad 100644 --- a/WebCore/bindings/js/JSSVGTransformListCustom.cpp +++ b/WebCore/bindings/js/JSSVGTransformListCustom.cpp @@ -33,7 +33,7 @@ namespace WebCore { typedef SVGPODListItem<SVGTransform> PODListItem; typedef SVGList<RefPtr<PODListItem> > SVGTransformListBase; -static JSValuePtr finishGetter(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGTransformList* list, PassRefPtr<PODListItem> item) +static JSValue finishGetter(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGTransformList* list, PassRefPtr<PODListItem> item) { if (ec) { setDOMException(exec, ec); @@ -42,7 +42,7 @@ static JSValuePtr finishGetter(ExecState* exec, ExceptionCode& ec, SVGElement* c return toJS(exec, JSSVGPODTypeWrapperCreatorForList<SVGTransform>::create(item.get(), list->associatedAttributeName()).get(), context); } -static JSValuePtr finishSetter(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGTransformList* list, PassRefPtr<PODListItem> item) +static JSValue finishSetter(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGTransformList* list, PassRefPtr<PODListItem> item) { if (ec) { setDOMException(exec, ec); @@ -53,7 +53,7 @@ static JSValuePtr finishSetter(ExecState* exec, ExceptionCode& ec, SVGElement* c return toJS(exec, JSSVGPODTypeWrapperCreatorForList<SVGTransform>::create(item.get(), attributeName).get(), context); } -static JSValuePtr finishSetterReadOnlyResult(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGTransformList* list, PassRefPtr<PODListItem> item) +static JSValue finishSetterReadOnlyResult(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGTransformList* list, PassRefPtr<PODListItem> item) { if (ec) { setDOMException(exec, ec); @@ -63,7 +63,7 @@ static JSValuePtr finishSetterReadOnlyResult(ExecState* exec, ExceptionCode& ec, return toJS(exec, JSSVGStaticPODTypeWrapper<SVGTransform>::create(*item).get(), context); } -JSValuePtr JSSVGTransformList::clear(ExecState* exec, const ArgList&) +JSValue JSSVGTransformList::clear(ExecState* exec, const ArgList&) { ExceptionCode ec = 0; impl()->clear(ec); @@ -72,18 +72,18 @@ JSValuePtr JSSVGTransformList::clear(ExecState* exec, const ArgList&) return jsUndefined(); } -JSValuePtr JSSVGTransformList::initialize(ExecState* exec, const ArgList& args) +JSValue JSSVGTransformList::initialize(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; SVGTransformListBase* listImp = impl(); return finishSetter(exec, ec, context(), impl(), - listImp->initialize(PODListItem::copy(toSVGTransform(args.at(exec, 0))), ec)); + listImp->initialize(PODListItem::copy(toSVGTransform(args.at(0))), ec)); } -JSValuePtr JSSVGTransformList::getItem(ExecState* exec, const ArgList& args) +JSValue JSSVGTransformList::getItem(ExecState* exec, const ArgList& args) { bool indexOk; - unsigned index = args.at(exec, 0).toUInt32(exec, indexOk); + unsigned index = args.at(0).toUInt32(exec, indexOk); if (!indexOk) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); @@ -95,10 +95,10 @@ JSValuePtr JSSVGTransformList::getItem(ExecState* exec, const ArgList& args) listImp->getItem(index, ec)); } -JSValuePtr JSSVGTransformList::insertItemBefore(ExecState* exec, const ArgList& args) +JSValue JSSVGTransformList::insertItemBefore(ExecState* exec, const ArgList& args) { bool indexOk; - unsigned index = args.at(exec, 1).toUInt32(exec, indexOk); + unsigned index = args.at(1).toUInt32(exec, indexOk); if (!indexOk) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); @@ -107,13 +107,13 @@ JSValuePtr JSSVGTransformList::insertItemBefore(ExecState* exec, const ArgList& ExceptionCode ec = 0; SVGTransformListBase* listImp = impl(); return finishSetter(exec, ec, context(), impl(), - listImp->insertItemBefore(PODListItem::copy(toSVGTransform(args.at(exec, 0))), index, ec)); + listImp->insertItemBefore(PODListItem::copy(toSVGTransform(args.at(0))), index, ec)); } -JSValuePtr JSSVGTransformList::replaceItem(ExecState* exec, const ArgList& args) +JSValue JSSVGTransformList::replaceItem(ExecState* exec, const ArgList& args) { bool indexOk; - unsigned index = args.at(exec, 1).toUInt32(exec, indexOk); + unsigned index = args.at(1).toUInt32(exec, indexOk); if (!indexOk) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); @@ -122,13 +122,13 @@ JSValuePtr JSSVGTransformList::replaceItem(ExecState* exec, const ArgList& args) ExceptionCode ec = 0; SVGTransformListBase* listImp = impl(); return finishSetter(exec, ec, context(), impl(), - listImp->replaceItem(PODListItem::copy(toSVGTransform(args.at(exec, 0))), index, ec)); + listImp->replaceItem(PODListItem::copy(toSVGTransform(args.at(0))), index, ec)); } -JSValuePtr JSSVGTransformList::removeItem(ExecState* exec, const ArgList& args) +JSValue JSSVGTransformList::removeItem(ExecState* exec, const ArgList& args) { bool indexOk; - unsigned index = args.at(exec, 0).toUInt32(exec, indexOk); + unsigned index = args.at(0).toUInt32(exec, indexOk); if (!indexOk) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); @@ -140,12 +140,12 @@ JSValuePtr JSSVGTransformList::removeItem(ExecState* exec, const ArgList& args) listImp->removeItem(index, ec)); } -JSValuePtr JSSVGTransformList::appendItem(ExecState* exec, const ArgList& args) +JSValue JSSVGTransformList::appendItem(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; SVGTransformListBase* listImp = impl(); return finishSetter(exec, ec, context(), impl(), - listImp->appendItem(PODListItem::copy(toSVGTransform(args.at(exec, 0))), ec)); + listImp->appendItem(PODListItem::copy(toSVGTransform(args.at(0))), ec)); } } diff --git a/WebCore/bindings/js/JSStorageCustom.cpp b/WebCore/bindings/js/JSStorageCustom.cpp index a72898e..bc43d79 100644 --- a/WebCore/bindings/js/JSStorageCustom.cpp +++ b/WebCore/bindings/js/JSStorageCustom.cpp @@ -41,7 +41,7 @@ bool JSStorage::canGetItemsForName(ExecState*, Storage* impl, const Identifier& return impl->contains(propertyName); } -JSValuePtr JSStorage::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSStorage::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { JSStorage* thisObj = static_cast<JSStorage*>(asObject(slot.slotBase())); return jsStringOrNull(exec, thisObj->impl()->getItem(propertyName)); @@ -56,7 +56,7 @@ bool JSStorage::deleteProperty(ExecState* exec, const Identifier& propertyName) if (getStaticValueSlot<JSStorage, Base>(exec, s_info.propHashTable(exec), this, propertyName, slot)) return false; - JSValuePtr prototype = this->prototype(); + JSValue prototype = this->prototype(); if (prototype.isObject() && asObject(prototype)->hasProperty(exec, propertyName)) return false; @@ -74,7 +74,7 @@ bool JSStorage::customGetPropertyNames(ExecState* exec, PropertyNameArray& prope return false; } -bool JSStorage::customPut(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot&) +bool JSStorage::customPut(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot&) { // Only perform the custom put if the object doesn't have a native property by this name. // Since hasProperty() would end up calling canGetItemsForName() and be fooled, we need to check @@ -83,11 +83,11 @@ bool JSStorage::customPut(ExecState* exec, const Identifier& propertyName, JSVal if (getStaticValueSlot<JSStorage, Base>(exec, s_info.propHashTable(exec), this, propertyName, slot)) return false; - JSValuePtr prototype = this->prototype(); + JSValue prototype = this->prototype(); if (prototype.isObject() && asObject(prototype)->hasProperty(exec, propertyName)) return false; - String stringValue = valueToStringWithNullCheck(exec, value); + String stringValue = value.toString(exec); if (exec->hadException()) return true; diff --git a/WebCore/bindings/js/JSStyleSheetCustom.cpp b/WebCore/bindings/js/JSStyleSheetCustom.cpp index 2cadcb4..f8146bd 100644 --- a/WebCore/bindings/js/JSStyleSheetCustom.cpp +++ b/WebCore/bindings/js/JSStyleSheetCustom.cpp @@ -35,7 +35,7 @@ using namespace JSC; namespace WebCore { -JSValuePtr toJS(ExecState* exec, StyleSheet* styleSheet) +JSValue toJS(ExecState* exec, StyleSheet* styleSheet) { if (!styleSheet) return jsNull(); diff --git a/WebCore/bindings/js/JSStyleSheetListCustom.cpp b/WebCore/bindings/js/JSStyleSheetListCustom.cpp index ea41687..1da6418 100644 --- a/WebCore/bindings/js/JSStyleSheetListCustom.cpp +++ b/WebCore/bindings/js/JSStyleSheetListCustom.cpp @@ -40,7 +40,7 @@ bool JSStyleSheetList::canGetItemsForName(ExecState*, StyleSheetList* styleSheet return styleSheetList->getNamedItem(propertyName); } -JSValuePtr JSStyleSheetList::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) +JSValue JSStyleSheetList::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot) { JSStyleSheetList* thisObj = static_cast<JSStyleSheetList*>(asObject(slot.slotBase())); HTMLStyleElement* element = thisObj->impl()->getNamedItem(propertyName); diff --git a/WebCore/bindings/js/JSTextCustom.cpp b/WebCore/bindings/js/JSTextCustom.cpp index 8118aef..9e66826 100644 --- a/WebCore/bindings/js/JSTextCustom.cpp +++ b/WebCore/bindings/js/JSTextCustom.cpp @@ -32,7 +32,7 @@ using namespace JSC; namespace WebCore { -JSValuePtr toJSNewlyCreated(ExecState* exec, Text* text) +JSValue toJSNewlyCreated(ExecState* exec, Text* text) { if (!text) return jsNull(); diff --git a/WebCore/bindings/js/JSTreeWalkerCustom.cpp b/WebCore/bindings/js/JSTreeWalkerCustom.cpp index aca0f93..6369017 100644 --- a/WebCore/bindings/js/JSTreeWalkerCustom.cpp +++ b/WebCore/bindings/js/JSTreeWalkerCustom.cpp @@ -37,7 +37,7 @@ void JSTreeWalker::mark() DOMObject::mark(); } -JSValuePtr JSTreeWalker::parentNode(ExecState* exec, const ArgList&) +JSValue JSTreeWalker::parentNode(ExecState* exec, const ArgList&) { Node* node = impl()->parentNode(exec); if (exec->hadException()) @@ -45,7 +45,7 @@ JSValuePtr JSTreeWalker::parentNode(ExecState* exec, const ArgList&) return toJS(exec, node); } -JSValuePtr JSTreeWalker::firstChild(ExecState* exec, const ArgList&) +JSValue JSTreeWalker::firstChild(ExecState* exec, const ArgList&) { Node* node = impl()->firstChild(exec); if (exec->hadException()) @@ -53,7 +53,7 @@ JSValuePtr JSTreeWalker::firstChild(ExecState* exec, const ArgList&) return toJS(exec, node); } -JSValuePtr JSTreeWalker::lastChild(ExecState* exec, const ArgList&) +JSValue JSTreeWalker::lastChild(ExecState* exec, const ArgList&) { Node* node = impl()->lastChild(exec); if (exec->hadException()) @@ -61,7 +61,7 @@ JSValuePtr JSTreeWalker::lastChild(ExecState* exec, const ArgList&) return toJS(exec, node); } -JSValuePtr JSTreeWalker::nextSibling(ExecState* exec, const ArgList&) +JSValue JSTreeWalker::nextSibling(ExecState* exec, const ArgList&) { Node* node = impl()->nextSibling(exec); if (exec->hadException()) @@ -69,7 +69,7 @@ JSValuePtr JSTreeWalker::nextSibling(ExecState* exec, const ArgList&) return toJS(exec, node); } -JSValuePtr JSTreeWalker::previousSibling(ExecState* exec, const ArgList&) +JSValue JSTreeWalker::previousSibling(ExecState* exec, const ArgList&) { Node* node = impl()->previousSibling(exec); if (exec->hadException()) @@ -77,7 +77,7 @@ JSValuePtr JSTreeWalker::previousSibling(ExecState* exec, const ArgList&) return toJS(exec, node); } -JSValuePtr JSTreeWalker::previousNode(ExecState* exec, const ArgList&) +JSValue JSTreeWalker::previousNode(ExecState* exec, const ArgList&) { Node* node = impl()->previousNode(exec); if (exec->hadException()) @@ -85,7 +85,7 @@ JSValuePtr JSTreeWalker::previousNode(ExecState* exec, const ArgList&) return toJS(exec, node); } -JSValuePtr JSTreeWalker::nextNode(ExecState* exec, const ArgList&) +JSValue JSTreeWalker::nextNode(ExecState* exec, const ArgList&) { Node* node = impl()->nextNode(exec); if (exec->hadException()) diff --git a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp index 3b97eb1..c7fe4a5 100644 --- a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp +++ b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp @@ -38,7 +38,7 @@ const ClassInfo JSWebKitCSSMatrixConstructor::s_info = { "WebKitCSSMatrixConstru JSWebKitCSSMatrixConstructor::JSWebKitCSSMatrixConstructor(ExecState* exec) : DOMObject(JSWebKitCSSMatrixConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) { - putDirect(exec->propertyNames().prototype, JSWebKitCSSMatrixPrototype::self(exec), None); + putDirect(exec->propertyNames().prototype, JSWebKitCSSMatrixPrototype::self(exec, exec->lexicalGlobalObject()), None); putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum); } @@ -46,7 +46,7 @@ static JSObject* constructWebKitCSSMatrix(ExecState* exec, JSObject*, const ArgL { String s; if (args.size() >= 1) - s = args.at(exec, 0).toString(exec); + s = args.at(0).toString(exec); ExceptionCode ec = 0; RefPtr<WebKitCSSMatrix> matrix = WebKitCSSMatrix::create(s, ec); diff --git a/WebCore/bindings/js/JSWebKitPointConstructor.cpp b/WebCore/bindings/js/JSWebKitPointConstructor.cpp index c3a8ea6..c7d4e36 100644 --- a/WebCore/bindings/js/JSWebKitPointConstructor.cpp +++ b/WebCore/bindings/js/JSWebKitPointConstructor.cpp @@ -39,7 +39,7 @@ const ClassInfo JSWebKitPointConstructor::s_info = { "WebKitPointConstructor", 0 JSWebKitPointConstructor::JSWebKitPointConstructor(ExecState* exec) : DOMObject(JSWebKitPointConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) { - putDirect(exec->propertyNames().prototype, JSWebKitPointPrototype::self(exec), None); + putDirect(exec->propertyNames().prototype, JSWebKitPointPrototype::self(exec, exec->lexicalGlobalObject()), None); putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum); } @@ -48,8 +48,8 @@ static JSObject* constructWebKitPoint(ExecState* exec, JSObject*, const ArgList& float x = 0; float y = 0; if (args.size() >= 2) { - x = (float)args.at(exec, 0).toNumber(exec); - y = (float)args.at(exec, 1).toNumber(exec); + x = (float)args.at(0).toNumber(exec); + y = (float)args.at(1).toNumber(exec); if (isnan(x)) x = 0; if (isnan(y)) diff --git a/WebCore/bindings/js/JSWorkerConstructor.cpp b/WebCore/bindings/js/JSWorkerConstructor.cpp index a9f2f74..8ea6718 100644 --- a/WebCore/bindings/js/JSWorkerConstructor.cpp +++ b/WebCore/bindings/js/JSWorkerConstructor.cpp @@ -44,7 +44,7 @@ const ClassInfo JSWorkerConstructor::s_info = { "WorkerConstructor", 0, 0, 0 }; JSWorkerConstructor::JSWorkerConstructor(ExecState* exec) : DOMObject(JSWorkerConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) { - putDirect(exec->propertyNames().prototype, JSWorkerPrototype::self(exec), None); + putDirect(exec->propertyNames().prototype, JSWorkerPrototype::self(exec, exec->lexicalGlobalObject()), None); putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum); } @@ -53,7 +53,7 @@ static JSObject* constructWorker(ExecState* exec, JSObject*, const ArgList& args if (args.size() == 0) return throwError(exec, SyntaxError, "Not enough arguments"); - UString scriptURL = args.at(exec, 0).toString(exec); + UString scriptURL = args.at(0).toString(exec); if (exec->hadException()) return 0; diff --git a/WebCore/bindings/js/JSWorkerContextBase.cpp b/WebCore/bindings/js/JSWorkerContextBase.cpp index c948b85..c71f45b 100644 --- a/WebCore/bindings/js/JSWorkerContextBase.cpp +++ b/WebCore/bindings/js/JSWorkerContextBase.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2009 Google Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,36 +31,17 @@ #include "JSWorkerContextBase.h" -#include "Event.h" -#include "JSDOMBinding.h" -#include "JSEventListener.h" -#include "JSMessageChannelConstructor.h" -#include "JSMessageEvent.h" -#include "JSMessagePort.h" -#include "JSWorkerLocation.h" -#include "JSWorkerNavigator.h" -#include "JSXMLHttpRequestConstructor.h" +#include "JSWorkerContext.h" #include "WorkerContext.h" -#include "WorkerLocation.h" using namespace JSC; -/* -@begin JSWorkerContextBaseTable -# -- Constructors -- - XMLHttpRequest jsWorkerContextBaseXMLHttpRequest DontDelete -@end -*/ - -static JSValuePtr jsWorkerContextBaseXMLHttpRequest(ExecState*, const Identifier&, const PropertySlot&); -static void setJSWorkerContextBaseXMLHttpRequest(ExecState*, JSObject*, JSValuePtr); - -#include "JSWorkerContextBase.lut.h" - namespace WebCore { ASSERT_CLASS_FITS_IN_CELL(JSWorkerContextBase); +const ClassInfo JSWorkerContextBase::s_info = { "WorkerContext", 0, 0, 0 }; + JSWorkerContextBase::JSWorkerContextBase(PassRefPtr<JSC::Structure> structure, PassRefPtr<WorkerContext> impl) : JSDOMGlobalObject(structure, new JSDOMGlobalObjectData, this) , m_impl(impl) @@ -76,45 +57,16 @@ ScriptExecutionContext* JSWorkerContextBase::scriptExecutionContext() const return m_impl.get(); } -static const HashTable* getJSWorkerContextBaseTable(ExecState* exec) -{ - return getHashTableForGlobalData(exec->globalData(), &JSWorkerContextBaseTable); -} - -const ClassInfo JSWorkerContextBase::s_info = { "WorkerContext", 0, 0, getJSWorkerContextBaseTable }; - -void JSWorkerContextBase::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot) -{ - lookupPut<JSWorkerContextBase, Base>(exec, propertyName, value, getJSWorkerContextBaseTable(exec), this, slot); -} - -bool JSWorkerContextBase::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +JSValue toJS(ExecState*, WorkerContext* workerContext) { - const HashEntry* entry = getJSWorkerContextBaseTable(exec)->entry(exec, propertyName); - if (entry) { - if (entry->attributes() & Function) - setUpStaticFunctionSlot(exec, entry, this, propertyName, slot); - else - slot.setCustom(this, entry->propertyGetter()); - return true; - } - - return Base::getOwnPropertySlot(exec, propertyName, slot); + if (!workerContext) + return jsNull(); + WorkerScriptController* script = workerContext->script(); + if (!script) + return jsNull(); + return script->workerContextWrapper(); } } // namespace WebCore -using namespace WebCore; - -JSValuePtr jsWorkerContextBaseXMLHttpRequest(ExecState* exec, const Identifier&, const PropertySlot& slot) -{ - return getDOMConstructor<JSXMLHttpRequestConstructor>(exec, static_cast<JSWorkerContextBase*>(asObject(slot.slotBase()))); -} - -void setJSWorkerContextBaseXMLHttpRequest(ExecState* exec, JSObject* thisObject, JSValuePtr value) -{ - // Shadowing a built-in constructor - static_cast<JSWorkerContextBase*>(thisObject)->putDirect(Identifier(exec, "XMLHttpRequest"), value); -} - #endif // ENABLE(WORKERS) diff --git a/WebCore/bindings/js/JSWorkerContextBase.h b/WebCore/bindings/js/JSWorkerContextBase.h index 5dc1921..dcbc5c3 100644 --- a/WebCore/bindings/js/JSWorkerContextBase.h +++ b/WebCore/bindings/js/JSWorkerContextBase.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -41,19 +41,19 @@ namespace WebCore { JSWorkerContextBase(PassRefPtr<JSC::Structure>, PassRefPtr<WorkerContext>); virtual ~JSWorkerContextBase(); - virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValuePtr, JSC::PutPropertySlot&); virtual const JSC::ClassInfo* classInfo() const { return &s_info; } static const JSC::ClassInfo s_info; WorkerContext* impl() const { return m_impl.get(); } virtual ScriptExecutionContext* scriptExecutionContext() const; - bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&); - private: RefPtr<WorkerContext> m_impl; }; + // Returns a JSWorkerContext or jsNull() + JSC::JSValue toJS(JSC::ExecState*, WorkerContext*); + } // namespace WebCore #endif // ENABLE(WORKERS) diff --git a/WebCore/bindings/js/JSWorkerContextCustom.cpp b/WebCore/bindings/js/JSWorkerContextCustom.cpp index a28cb75..6824914 100644 --- a/WebCore/bindings/js/JSWorkerContextCustom.cpp +++ b/WebCore/bindings/js/JSWorkerContextCustom.cpp @@ -31,27 +31,29 @@ #include "JSDOMBinding.h" #include "JSEventListener.h" +#include "JSWorkerLocation.h" +#include "JSWorkerNavigator.h" +#include "JSXMLHttpRequestConstructor.h" #include "ScheduledAction.h" #include "WorkerContext.h" +#include "WorkerLocation.h" +#include "WorkerNavigator.h" #include <interpreter/Interpreter.h> using namespace JSC; namespace WebCore { -bool JSWorkerContext::customGetOwnPropertySlot(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::PropertySlot& slot) -{ - // Look for overrides before looking at any of our own properties. - if (JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot)) - return true; - return false; -} - void JSWorkerContext::mark() { Base::mark(); - markActiveObjectsForContext(*globalData(), scriptExecutionContext()); + JSGlobalData& globalData = *this->globalData(); + + markActiveObjectsForContext(globalData, scriptExecutionContext()); + + markDOMObjectWrapper(globalData, impl()->optionalLocation()); + markDOMObjectWrapper(globalData, impl()->optionalNavigator()); markIfNotNull(impl()->onmessage()); @@ -60,28 +62,31 @@ void JSWorkerContext::mark() EventListenersMap& eventListeners = impl()->eventListeners(); for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) { for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) - (*vecIter)->mark(); + (*vecIter)->markJSFunction(); } } -JSValuePtr JSWorkerContext::self(ExecState*) const +bool JSWorkerContext::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { - return JSValuePtr(this); + // Look for overrides before looking at any of our own properties. + if (JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot)) + return true; + return false; } -void JSWorkerContext::setSelf(ExecState* exec, JSValuePtr value) +JSValue JSWorkerContext::xmlHttpRequest(ExecState* exec) const { - putDirect(Identifier(exec, "self"), value); + return getDOMConstructor<JSXMLHttpRequestConstructor>(exec, this); } -JSValuePtr JSWorkerContext::importScripts(ExecState* exec, const ArgList& args) +JSValue JSWorkerContext::importScripts(ExecState* exec, const ArgList& args) { if (!args.size()) return jsUndefined(); Vector<String> urls; for (unsigned i = 0; i < args.size(); i++) { - urls.append(args.at(exec, i).toString(exec)); + urls.append(args.at(i).toString(exec)); if (exec->hadException()) return jsUndefined(); } @@ -89,7 +94,7 @@ JSValuePtr JSWorkerContext::importScripts(ExecState* exec, const ArgList& args) int signedLineNumber; intptr_t sourceID; UString sourceURL; - JSValuePtr function; + JSValue function; exec->interpreter()->retrieveLastCaller(exec, signedLineNumber, sourceID, sourceURL, function); impl()->importScripts(urls, sourceURL, signedLineNumber >= 0 ? signedLineNumber : 0, ec); @@ -97,58 +102,40 @@ JSValuePtr JSWorkerContext::importScripts(ExecState* exec, const ArgList& args) return jsUndefined(); } -JSValuePtr JSWorkerContext::addEventListener(ExecState* exec, const ArgList& args) +JSValue JSWorkerContext::addEventListener(ExecState* exec, const ArgList& args) { - RefPtr<JSEventListener> listener = findOrCreateJSEventListener(exec, args.at(exec, 1)); + RefPtr<JSEventListener> listener = findOrCreateJSEventListener(args.at(1)); if (!listener) return jsUndefined(); - impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec)); + impl()->addEventListener(args.at(0).toString(exec), listener.release(), args.at(2).toBoolean(exec)); return jsUndefined(); } -JSValuePtr JSWorkerContext::removeEventListener(ExecState* exec, const ArgList& args) +JSValue JSWorkerContext::removeEventListener(ExecState* exec, const ArgList& args) { - JSEventListener* listener = findJSEventListener(exec, args.at(exec, 1)); + JSEventListener* listener = findJSEventListener(args.at(1)); if (!listener) return jsUndefined(); - impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec)); + impl()->removeEventListener(args.at(0).toString(exec), listener, args.at(2).toBoolean(exec)); return jsUndefined(); } -static JSValuePtr setTimeoutOrInterval(ExecState* exec, WorkerContext* workerContext, const ArgList& args, bool singleShot) +JSValue JSWorkerContext::setTimeout(ExecState* exec, const ArgList& args) { - JSValuePtr v = args.at(exec, 0); - int delay = args.at(exec, 1).toInt32(exec); - if (v.isString()) - return jsNumber(exec, workerContext->installTimeout(new ScheduledAction(asString(v)->value()), delay, singleShot)); - CallData callData; - if (v.getCallData(callData) == CallTypeNone) + ScheduledAction* action = ScheduledAction::create(exec, args); + if (exec->hadException()) return jsUndefined(); - ArgList argsTail; - args.getSlice(2, argsTail); - return jsNumber(exec, workerContext->installTimeout(new ScheduledAction(exec, v, argsTail), delay, singleShot)); + int delay = args.at(1).toInt32(exec); + return jsNumber(exec, impl()->setTimeout(action, delay)); } -JSValuePtr JSWorkerContext::setTimeout(ExecState* exec, const ArgList& args) +JSValue JSWorkerContext::setInterval(ExecState* exec, const ArgList& args) { - return setTimeoutOrInterval(exec, impl(), args, true); -} - -JSValuePtr JSWorkerContext::clearTimeout(ExecState* exec, const ArgList& args) -{ - impl()->removeTimeout(args.at(exec, 0).toInt32(exec)); - return jsUndefined(); -} - -JSValuePtr JSWorkerContext::setInterval(ExecState* exec, const ArgList& args) -{ - return setTimeoutOrInterval(exec, impl(), args, false); -} - -JSValuePtr JSWorkerContext::clearInterval(ExecState* exec, const ArgList& args) -{ - impl()->removeTimeout(args.at(exec, 0).toInt32(exec)); - return jsUndefined(); + ScheduledAction* action = ScheduledAction::create(exec, args); + if (exec->hadException()) + return jsUndefined(); + int delay = args.at(1).toInt32(exec); + return jsNumber(exec, impl()->setInterval(action, delay)); } } // namespace WebCore diff --git a/WebCore/bindings/js/JSWorkerCustom.cpp b/WebCore/bindings/js/JSWorkerCustom.cpp index 12103d3..f4d3033 100644 --- a/WebCore/bindings/js/JSWorkerCustom.cpp +++ b/WebCore/bindings/js/JSWorkerCustom.cpp @@ -49,31 +49,31 @@ void JSWorker::mark() 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) - (*vecIter)->mark(); + (*vecIter)->markJSFunction(); } } -JSValuePtr JSWorker::addEventListener(ExecState* exec, const ArgList& args) +JSValue JSWorker::addEventListener(ExecState* exec, const ArgList& args) { JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1)); + RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(args.at(1)); if (!listener) return jsUndefined(); - impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec)); + impl()->addEventListener(args.at(0).toString(exec), listener.release(), args.at(2).toBoolean(exec)); return jsUndefined(); } -JSValuePtr JSWorker::removeEventListener(ExecState* exec, const ArgList& args) +JSValue JSWorker::removeEventListener(ExecState* exec, const ArgList& args) { JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - JSEventListener* listener = globalObject->findJSEventListener(exec, args.at(exec, 1)); + JSEventListener* listener = globalObject->findJSEventListener(args.at(1)); if (!listener) return jsUndefined(); - impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec)); + impl()->removeEventListener(args.at(0).toString(exec), listener, args.at(2).toBoolean(exec)); return jsUndefined(); } diff --git a/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp b/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp index a7f8ab0..65cdfc2 100644 --- a/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp +++ b/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp @@ -32,11 +32,11 @@ ASSERT_CLASS_FITS_IN_CELL(JSXMLHttpRequestConstructor); const ClassInfo JSXMLHttpRequestConstructor::s_info = { "XMLHttpRequestConstructor", 0, 0, 0 }; -JSXMLHttpRequestConstructor::JSXMLHttpRequestConstructor(ExecState* exec, ScriptExecutionContext* scriptExecutionContext) +JSXMLHttpRequestConstructor::JSXMLHttpRequestConstructor(ExecState* exec, JSDOMGlobalObject* globalObject) : DOMObject(JSXMLHttpRequestConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) - , m_globalObject(toJSDOMGlobalObject(scriptExecutionContext)) + , m_globalObject(globalObject) { - putDirect(exec->propertyNames().prototype, JSXMLHttpRequestPrototype::self(exec), None); + putDirect(exec->propertyNames().prototype, JSXMLHttpRequestPrototype::self(exec, exec->lexicalGlobalObject()), None); } ScriptExecutionContext* JSXMLHttpRequestConstructor::scriptExecutionContext() const @@ -46,7 +46,11 @@ ScriptExecutionContext* JSXMLHttpRequestConstructor::scriptExecutionContext() co static JSObject* constructXMLHttpRequest(ExecState* exec, JSObject* constructor, const ArgList&) { - RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(static_cast<JSXMLHttpRequestConstructor*>(constructor)->scriptExecutionContext()); + ScriptExecutionContext* context = static_cast<JSXMLHttpRequestConstructor*>(constructor)->scriptExecutionContext(); + if (!context) + return throwError(exec, ReferenceError, "XMLHttpRequest constructor associated document is unavailable"); + + RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(context); return CREATE_DOM_OBJECT_WRAPPER(exec, XMLHttpRequest, xmlHttpRequest.get()); } diff --git a/WebCore/bindings/js/JSXMLHttpRequestConstructor.h b/WebCore/bindings/js/JSXMLHttpRequestConstructor.h index 01d1f85..978a9f0 100644 --- a/WebCore/bindings/js/JSXMLHttpRequestConstructor.h +++ b/WebCore/bindings/js/JSXMLHttpRequestConstructor.h @@ -26,7 +26,7 @@ namespace WebCore { class JSXMLHttpRequestConstructor : public DOMObject { public: - JSXMLHttpRequestConstructor(JSC::ExecState*, ScriptExecutionContext*); + JSXMLHttpRequestConstructor(JSC::ExecState*, JSDOMGlobalObject*); ScriptExecutionContext* scriptExecutionContext() const; static const JSC::ClassInfo s_info; diff --git a/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp b/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp index a7f78b7..06a5817 100644 --- a/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp +++ b/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp @@ -71,28 +71,28 @@ void JSXMLHttpRequest::mark() 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) - (*vecIter)->mark(); + (*vecIter)->markJSFunction(); } } // Custom functions -JSValuePtr JSXMLHttpRequest::open(ExecState* exec, const ArgList& args) +JSValue JSXMLHttpRequest::open(ExecState* exec, const ArgList& args) { if (args.size() < 2) return throwError(exec, SyntaxError, "Not enough arguments"); - const KURL& url = impl()->scriptExecutionContext()->completeURL(args.at(exec, 1).toString(exec)); - String method = args.at(exec, 0).toString(exec); + const KURL& url = impl()->scriptExecutionContext()->completeURL(args.at(1).toString(exec)); + String method = args.at(0).toString(exec); bool async = true; if (args.size() >= 3) - async = args.at(exec, 2).toBoolean(exec); + async = args.at(2).toBoolean(exec); ExceptionCode ec = 0; - if (args.size() >= 4 && !args.at(exec, 3).isUndefined()) { - String user = valueToStringWithNullCheck(exec, args.at(exec, 3)); + if (args.size() >= 4 && !args.at(3).isUndefined()) { + String user = valueToStringWithNullCheck(exec, args.at(3)); - if (args.size() >= 5 && !args.at(exec, 4).isUndefined()) { - String password = valueToStringWithNullCheck(exec, args.at(exec, 4)); + if (args.size() >= 5 && !args.at(4).isUndefined()) { + String password = valueToStringWithNullCheck(exec, args.at(4)); impl()->open(method, url, async, user, password, ec); } else impl()->open(method, url, async, user, ec); @@ -103,24 +103,24 @@ JSValuePtr JSXMLHttpRequest::open(ExecState* exec, const ArgList& args) return jsUndefined(); } -JSValuePtr JSXMLHttpRequest::setRequestHeader(ExecState* exec, const ArgList& args) +JSValue JSXMLHttpRequest::setRequestHeader(ExecState* exec, const ArgList& args) { if (args.size() < 2) return throwError(exec, SyntaxError, "Not enough arguments"); ExceptionCode ec = 0; - impl()->setRequestHeader(args.at(exec, 0).toString(exec), args.at(exec, 1).toString(exec), ec); + impl()->setRequestHeader(args.at(0).toString(exec), args.at(1).toString(exec), ec); setDOMException(exec, ec); return jsUndefined(); } -JSValuePtr JSXMLHttpRequest::send(ExecState* exec, const ArgList& args) +JSValue JSXMLHttpRequest::send(ExecState* exec, const ArgList& args) { ExceptionCode ec = 0; if (args.isEmpty()) impl()->send(ec); else { - JSValuePtr val = args.at(exec, 0); + JSValue val = args.at(0); if (val.isUndefinedOrNull()) impl()->send(ec); else if (val.isObject(&JSDocument::s_info)) @@ -134,7 +134,7 @@ JSValuePtr JSXMLHttpRequest::send(ExecState* exec, const ArgList& args) int signedLineNumber; intptr_t sourceID; UString sourceURL; - JSValuePtr function; + JSValue function; exec->interpreter()->retrieveLastCaller(exec, signedLineNumber, sourceID, sourceURL, function); impl()->setLastSendLineNumber(signedLineNumber >= 0 ? signedLineNumber : 0); impl()->setLastSendURL(sourceURL); @@ -143,51 +143,51 @@ JSValuePtr JSXMLHttpRequest::send(ExecState* exec, const ArgList& args) return jsUndefined(); } -JSValuePtr JSXMLHttpRequest::getResponseHeader(ExecState* exec, const ArgList& args) +JSValue JSXMLHttpRequest::getResponseHeader(ExecState* exec, const ArgList& args) { if (args.size() < 1) return throwError(exec, SyntaxError, "Not enough arguments"); ExceptionCode ec = 0; - JSValuePtr header = jsStringOrNull(exec, impl()->getResponseHeader(args.at(exec, 0).toString(exec), ec)); + JSValue header = jsStringOrNull(exec, impl()->getResponseHeader(args.at(0).toString(exec), ec)); setDOMException(exec, ec); return header; } -JSValuePtr JSXMLHttpRequest::overrideMimeType(ExecState* exec, const ArgList& args) +JSValue JSXMLHttpRequest::overrideMimeType(ExecState* exec, const ArgList& args) { if (args.size() < 1) return throwError(exec, SyntaxError, "Not enough arguments"); - impl()->overrideMimeType(args.at(exec, 0).toString(exec)); + impl()->overrideMimeType(args.at(0).toString(exec)); return jsUndefined(); } -JSValuePtr JSXMLHttpRequest::addEventListener(ExecState* exec, const ArgList& args) +JSValue JSXMLHttpRequest::addEventListener(ExecState* exec, const ArgList& args) { JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1)); + RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(args.at(1)); if (!listener) return jsUndefined(); - impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec)); + impl()->addEventListener(args.at(0).toString(exec), listener.release(), args.at(2).toBoolean(exec)); return jsUndefined(); } -JSValuePtr JSXMLHttpRequest::removeEventListener(ExecState* exec, const ArgList& args) +JSValue JSXMLHttpRequest::removeEventListener(ExecState* exec, const ArgList& args) { JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - JSEventListener* listener = globalObject->findJSEventListener(exec, args.at(exec, 1)); + JSEventListener* listener = globalObject->findJSEventListener(args.at(1)); if (!listener) return jsUndefined(); - impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec)); + impl()->removeEventListener(args.at(0).toString(exec), listener, args.at(2).toBoolean(exec)); return jsUndefined(); } -JSValuePtr JSXMLHttpRequest::responseText(ExecState* exec) const +JSValue JSXMLHttpRequest::responseText(ExecState* exec) const { return jsOwnedStringOrNull(exec, impl()->responseText()); } diff --git a/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp b/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp index 26342e0..597010c 100644 --- a/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp +++ b/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp @@ -62,31 +62,31 @@ void JSXMLHttpRequestUpload::mark() 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) - (*vecIter)->mark(); + (*vecIter)->markJSFunction(); } } -JSValuePtr JSXMLHttpRequestUpload::addEventListener(ExecState* exec, const ArgList& args) +JSValue JSXMLHttpRequestUpload::addEventListener(ExecState* exec, const ArgList& args) { JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1)); + RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(args.at(1)); if (!listener) return jsUndefined(); - impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec)); + impl()->addEventListener(args.at(0).toString(exec), listener.release(), args.at(2).toBoolean(exec)); return jsUndefined(); } -JSValuePtr JSXMLHttpRequestUpload::removeEventListener(ExecState* exec, const ArgList& args) +JSValue JSXMLHttpRequestUpload::removeEventListener(ExecState* exec, const ArgList& args) { JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext()); if (!globalObject) return jsUndefined(); - JSEventListener* listener = globalObject->findJSEventListener(exec, args.at(exec, 1)); + JSEventListener* listener = globalObject->findJSEventListener(args.at(1)); if (!listener) return jsUndefined(); - impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec)); + impl()->removeEventListener(args.at(0).toString(exec), listener, args.at(2).toBoolean(exec)); return jsUndefined(); } diff --git a/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp b/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp index 448c832..807b017 100644 --- a/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp +++ b/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp @@ -44,7 +44,7 @@ const ClassInfo JSXSLTProcessorConstructor::s_info = { "XSLTProcessorConsructor" JSXSLTProcessorConstructor::JSXSLTProcessorConstructor(ExecState* exec) : DOMObject(JSXSLTProcessorConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) { - putDirect(exec->propertyNames().prototype, JSXSLTProcessorPrototype::self(exec), None); + putDirect(exec->propertyNames().prototype, JSXSLTProcessorPrototype::self(exec, exec->lexicalGlobalObject()), None); } static JSObject* constructXSLTProcessor(ExecState* exec, JSObject*, const ArgList&) diff --git a/WebCore/bindings/js/JSXSLTProcessorCustom.cpp b/WebCore/bindings/js/JSXSLTProcessorCustom.cpp index 8de2e54..01e53a6 100644 --- a/WebCore/bindings/js/JSXSLTProcessorCustom.cpp +++ b/WebCore/bindings/js/JSXSLTProcessorCustom.cpp @@ -46,9 +46,9 @@ using namespace JSC; namespace WebCore { -JSValuePtr JSXSLTProcessor::importStylesheet(ExecState* exec, const ArgList& args) +JSValue JSXSLTProcessor::importStylesheet(ExecState*, const ArgList& args) { - JSValuePtr nodeVal = args.at(exec, 0); + JSValue nodeVal = args.at(0); if (nodeVal.isObject(&JSNode::s_info)) { JSNode* node = static_cast<JSNode*>(asObject(nodeVal)); impl()->importStylesheet(node->impl()); @@ -58,10 +58,10 @@ JSValuePtr JSXSLTProcessor::importStylesheet(ExecState* exec, const ArgList& arg return jsUndefined(); } -JSValuePtr JSXSLTProcessor::transformToFragment(ExecState* exec, const ArgList& args) +JSValue JSXSLTProcessor::transformToFragment(ExecState* exec, const ArgList& args) { - JSValuePtr nodeVal = args.at(exec, 0); - JSValuePtr docVal = args.at(exec, 1); + JSValue nodeVal = args.at(0); + JSValue docVal = args.at(1); if (nodeVal.isObject(&JSNode::s_info) && docVal.isObject(&JSDocument::s_info)) { WebCore::Node* node = static_cast<JSNode*>(asObject(nodeVal))->impl(); Document* doc = static_cast<Document*>(static_cast<JSDocument*>(asObject(docVal))->impl()); @@ -71,9 +71,9 @@ JSValuePtr JSXSLTProcessor::transformToFragment(ExecState* exec, const ArgList& return jsUndefined(); } -JSValuePtr JSXSLTProcessor::transformToDocument(ExecState* exec, const ArgList& args) +JSValue JSXSLTProcessor::transformToDocument(ExecState* exec, const ArgList& args) { - JSValuePtr nodeVal = args.at(exec, 0); + JSValue nodeVal = args.at(0); if (nodeVal.isObject(&JSNode::s_info)) { JSNode* node = static_cast<JSNode*>(asObject(nodeVal)); RefPtr<Document> resultDocument = impl()->transformToDocument(node->impl()); @@ -85,33 +85,33 @@ JSValuePtr JSXSLTProcessor::transformToDocument(ExecState* exec, const ArgList& return jsUndefined(); } -JSValuePtr JSXSLTProcessor::setParameter(ExecState* exec, const ArgList& args) +JSValue JSXSLTProcessor::setParameter(ExecState* exec, const ArgList& args) { - if (args.at(exec, 1).isUndefinedOrNull() || args.at(exec, 2).isUndefinedOrNull()) + if (args.at(1).isUndefinedOrNull() || args.at(2).isUndefinedOrNull()) return jsUndefined(); // Throw exception? - String namespaceURI = args.at(exec, 0).toString(exec); - String localName = args.at(exec, 1).toString(exec); - String value = args.at(exec, 2).toString(exec); + String namespaceURI = args.at(0).toString(exec); + String localName = args.at(1).toString(exec); + String value = args.at(2).toString(exec); impl()->setParameter(namespaceURI, localName, value); return jsUndefined(); } -JSValuePtr JSXSLTProcessor::getParameter(ExecState* exec, const ArgList& args) +JSValue JSXSLTProcessor::getParameter(ExecState* exec, const ArgList& args) { - if (args.at(exec, 1).isUndefinedOrNull()) + if (args.at(1).isUndefinedOrNull()) return jsUndefined(); - String namespaceURI = args.at(exec, 0).toString(exec); - String localName = args.at(exec, 1).toString(exec); + String namespaceURI = args.at(0).toString(exec); + String localName = args.at(1).toString(exec); String value = impl()->getParameter(namespaceURI, localName); return jsStringOrUndefined(exec, value); } -JSValuePtr JSXSLTProcessor::removeParameter(ExecState* exec, const ArgList& args) +JSValue JSXSLTProcessor::removeParameter(ExecState* exec, const ArgList& args) { - if (args.at(exec, 1).isUndefinedOrNull()) + if (args.at(1).isUndefinedOrNull()) return jsUndefined(); - String namespaceURI = args.at(exec, 0).toString(exec); - String localName = args.at(exec, 1).toString(exec); + String namespaceURI = args.at(0).toString(exec); + String localName = args.at(1).toString(exec); impl()->removeParameter(namespaceURI, localName); return jsUndefined(); } diff --git a/WebCore/bindings/js/ScheduledAction.cpp b/WebCore/bindings/js/ScheduledAction.cpp index 986a96e..91bece7 100644 --- a/WebCore/bindings/js/ScheduledAction.cpp +++ b/WebCore/bindings/js/ScheduledAction.cpp @@ -1,7 +1,7 @@ /* * 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) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reseved. * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) * Copyright (C) 2009 Google Inc. All rights reseved. * @@ -31,30 +31,43 @@ #include "FrameLoader.h" #include "JSDOMBinding.h" #include "JSDOMWindow.h" -#ifdef ANDROID_FIX // these are generated files, need to check ENABLE(WORKERS) -#if ENABLE(WORKERS) -#include "JSWorkerContext.h" -#endif -#endif #include "ScriptController.h" #include "ScriptExecutionContext.h" #include "ScriptSourceCode.h" #include "ScriptValue.h" +#include <runtime/JSLock.h> + +#if ENABLE(WORKERS) +#include "JSWorkerContext.h" #include "WorkerContext.h" #include "WorkerThread.h" -#include <runtime/JSLock.h> +#endif using namespace JSC; namespace WebCore { -ScheduledAction::ScheduledAction(ExecState* exec, JSValuePtr function, const ArgList& args) +ScheduledAction* ScheduledAction::create(ExecState* exec, const ArgList& args) +{ + JSValue v = args.at(0); + CallData callData; + if (v.getCallData(callData) == CallTypeNone) { + UString string = v.toString(exec); + if (exec->hadException()) + return 0; + return new ScheduledAction(string); + } + ArgList argsTail; + args.getSlice(2, argsTail); + return new ScheduledAction(v, argsTail); +} + +ScheduledAction::ScheduledAction(JSValue function, const ArgList& args) : m_function(function) { ArgList::const_iterator end = args.end(); - for (ArgList::const_iterator it = args.begin(); it != end; ++it) { - m_args.append((*it).jsValue(exec)); - } + for (ArgList::const_iterator it = args.begin(); it != end; ++it) + m_args.append(*it); } void ScheduledAction::execute(ScriptExecutionContext* context) @@ -71,7 +84,7 @@ void ScheduledAction::execute(ScriptExecutionContext* context) #endif } -void ScheduledAction::executeFunctionInContext(JSGlobalObject* globalObject, JSValuePtr thisValue) +void ScheduledAction::executeFunctionInContext(JSGlobalObject* globalObject, JSValue thisValue) { ASSERT(m_function); JSLock lock(false); @@ -83,7 +96,7 @@ void ScheduledAction::executeFunctionInContext(JSGlobalObject* globalObject, JSV ExecState* exec = globalObject->globalExec(); - ArgList args; + MarkedArgumentBuffer args; size_t size = m_args.size(); for (size_t i = 0; i < size; ++i) args.append(m_args[i]); @@ -96,24 +109,6 @@ void ScheduledAction::executeFunctionInContext(JSGlobalObject* globalObject, JSV reportCurrentException(exec); } -#if ENABLE(WORKERS) -void ScheduledAction::execute(WorkerContext* workerContext) -{ - // In a Worker, the execution should always happen on a worker thread. - ASSERT(workerContext->thread()->threadID() == currentThread()); - - WorkerScriptController* scriptController = workerContext->script(); - - if (m_function) { - JSWorkerContext* contextWrapper = scriptController->workerContextWrapper(); - executeFunctionInContext(contextWrapper, contextWrapper); - } else { - ScriptSourceCode code(m_code, workerContext->url()); - scriptController->evaluate(code); - } -} -#endif // ENABLE(WORKERS) - void ScheduledAction::execute(Document* document) { JSDOMWindow* window = toJSDOMWindow(document->frame()); @@ -126,19 +121,31 @@ void ScheduledAction::execute(Document* document) frame->script()->setProcessingTimerCallback(true); - if (m_function) + if (m_function) { executeFunctionInContext(window, window->shell()); - else + Document::updateStyleForAllDocuments(); + } 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. - frame->document()->updateRendering(); - frame->script()->setProcessingTimerCallback(false); } +#if ENABLE(WORKERS) +void ScheduledAction::execute(WorkerContext* workerContext) +{ + // In a Worker, the execution should always happen on a worker thread. + ASSERT(workerContext->thread()->threadID() == currentThread()); + + WorkerScriptController* scriptController = workerContext->script(); + + if (m_function) { + JSWorkerContext* contextWrapper = scriptController->workerContextWrapper(); + executeFunctionInContext(contextWrapper, contextWrapper); + } else { + ScriptSourceCode code(m_code, workerContext->url()); + scriptController->evaluate(code); + } +} +#endif // ENABLE(WORKERS) + } // namespace WebCore diff --git a/WebCore/bindings/js/ScheduledAction.h b/WebCore/bindings/js/ScheduledAction.h index a1dbbe4..e7d0b75 100644 --- a/WebCore/bindings/js/ScheduledAction.h +++ b/WebCore/bindings/js/ScheduledAction.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reseved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 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 @@ -40,23 +40,25 @@ namespace WebCore { */ class ScheduledAction { public: - ScheduledAction(JSC::ExecState* exec, JSC::JSValuePtr function, const JSC::ArgList&); + static ScheduledAction* create(JSC::ExecState*, const JSC::ArgList&); + + void execute(ScriptExecutionContext*); + + private: + ScheduledAction(JSC::JSValue function, const JSC::ArgList&); ScheduledAction(const String& code) : m_code(code) { } - void execute(ScriptExecutionContext*); - - private: - void executeFunctionInContext(JSC::JSGlobalObject*, JSC::JSValuePtr thisValue); + void executeFunctionInContext(JSC::JSGlobalObject*, JSC::JSValue thisValue); void execute(Document*); #if ENABLE(WORKERS) void execute(WorkerContext*); #endif - JSC::ProtectedJSValuePtr m_function; - Vector<JSC::ProtectedJSValuePtr> m_args; + JSC::ProtectedJSValue m_function; + Vector<JSC::ProtectedJSValue> m_args; String m_code; }; diff --git a/WebCore/bindings/js/ScriptCachedFrameData.cpp b/WebCore/bindings/js/ScriptCachedFrameData.cpp index 955a368..213c708 100644 --- a/WebCore/bindings/js/ScriptCachedFrameData.cpp +++ b/WebCore/bindings/js/ScriptCachedFrameData.cpp @@ -50,6 +50,7 @@ ScriptCachedFrameData::ScriptCachedFrameData(Frame* frame) ScriptController* scriptController = frame->script(); if (scriptController->haveWindowShell()) { m_window = scriptController->windowShell()->window(); + scriptController->attachDebugger(0); } } diff --git a/WebCore/bindings/js/ScriptCallFrame.cpp b/WebCore/bindings/js/ScriptCallFrame.cpp index 29f380a..58168d0 100644 --- a/WebCore/bindings/js/ScriptCallFrame.cpp +++ b/WebCore/bindings/js/ScriptCallFrame.cpp @@ -38,14 +38,14 @@ using namespace JSC; namespace WebCore { -ScriptCallFrame::ScriptCallFrame(const UString& functionName, const UString& urlString, int lineNumber, ExecState* exec, const ArgList& args, unsigned skipArgumentCount) +ScriptCallFrame::ScriptCallFrame(const UString& functionName, const UString& urlString, int lineNumber, const ArgList& args, unsigned skipArgumentCount) : m_functionName(functionName) , m_sourceURL(urlString) , m_lineNumber(lineNumber) { size_t argumentCount = args.size(); for (size_t i = skipArgumentCount; i < argumentCount; ++i) - m_arguments.append(ScriptValue(args.at(exec, i))); + m_arguments.append(ScriptValue(args.at(i))); } ScriptCallFrame::~ScriptCallFrame() diff --git a/WebCore/bindings/js/ScriptCallFrame.h b/WebCore/bindings/js/ScriptCallFrame.h index 64a1a08..b8c0aba 100644 --- a/WebCore/bindings/js/ScriptCallFrame.h +++ b/WebCore/bindings/js/ScriptCallFrame.h @@ -50,7 +50,7 @@ namespace WebCore { // <https://bugs.webkit.org/show_bug.cgi?id=21180> class ScriptCallFrame { public: - ScriptCallFrame(const JSC::UString& functionName, const JSC::UString& urlString, int lineNumber, JSC::ExecState*, const JSC::ArgList&, unsigned skipArgumentCount); + ScriptCallFrame(const JSC::UString& functionName, const JSC::UString& urlString, int lineNumber, const JSC::ArgList&, unsigned skipArgumentCount); ~ScriptCallFrame(); const ScriptString& functionName() const { return m_functionName; } diff --git a/WebCore/bindings/js/ScriptCallStack.cpp b/WebCore/bindings/js/ScriptCallStack.cpp index d984bf4..021ede5 100644 --- a/WebCore/bindings/js/ScriptCallStack.cpp +++ b/WebCore/bindings/js/ScriptCallStack.cpp @@ -50,18 +50,18 @@ ScriptCallStack::ScriptCallStack(ExecState* exec, const ArgList& args, unsigned int signedLineNumber; intptr_t sourceID; UString urlString; - JSValuePtr function; + JSValue function; exec->interpreter()->retrieveLastCaller(exec, signedLineNumber, sourceID, urlString, function); if (function) { m_caller = asInternalFunction(function); unsigned lineNumber = signedLineNumber >= 0 ? signedLineNumber : 0; - m_frames.append(ScriptCallFrame(m_caller->name(&m_exec->globalData()), urlString, lineNumber, exec, args, skipArgumentCount)); + m_frames.append(ScriptCallFrame(m_caller->name(&m_exec->globalData()), urlString, lineNumber, args, skipArgumentCount)); } else { // Caller is unknown, but we should still add the frame, because // something called us, and gave us arguments. - m_frames.append(ScriptCallFrame(UString(), UString(), 0, exec, args, skipArgumentCount)); + m_frames.append(ScriptCallFrame(UString(), UString(), 0, args, skipArgumentCount)); } } @@ -90,11 +90,11 @@ void ScriptCallStack::initialize() if (!m_caller || m_initialized) return; - JSValuePtr func = m_exec->interpreter()->retrieveCaller(m_exec, m_caller); + JSValue func = m_exec->interpreter()->retrieveCaller(m_exec, m_caller); while (!func.isNull()) { InternalFunction* internalFunction = asInternalFunction(func); ArgList emptyArgList; - m_frames.append(ScriptCallFrame(internalFunction->name(&m_exec->globalData()), UString(), 0, 0, emptyArgList, 0)); + m_frames.append(ScriptCallFrame(internalFunction->name(&m_exec->globalData()), UString(), 0, emptyArgList, 0)); func = m_exec->interpreter()->retrieveCaller(m_exec, internalFunction); } m_initialized = true; diff --git a/WebCore/bindings/js/ScriptCallStack.h b/WebCore/bindings/js/ScriptCallStack.h index 7634ce3..1907564 100644 --- a/WebCore/bindings/js/ScriptCallStack.h +++ b/WebCore/bindings/js/ScriptCallStack.h @@ -38,7 +38,7 @@ namespace JSC { class ExecState; - class JSValuePtr; + class JSValue; } namespace WebCore { diff --git a/WebCore/bindings/js/ScriptController.cpp b/WebCore/bindings/js/ScriptController.cpp index fbca680..2f676c0 100644 --- a/WebCore/bindings/js/ScriptController.cpp +++ b/WebCore/bindings/js/ScriptController.cpp @@ -27,7 +27,6 @@ #include "GCController.h" #include "HTMLPlugInElement.h" #include "JSDocument.h" -#include "JSLazyEventListener.h" #include "NP_jsobject.h" #include "Page.h" #include "PageGroup.h" @@ -45,10 +44,11 @@ namespace WebCore { ScriptController::ScriptController(Frame* frame) : m_frame(frame) - , m_handlerLineno(0) + , m_handlerLineNumber(0) , m_sourceURL(0) , m_processingTimerCallback(false) , m_paused(false) + , m_allowPopupsFromPlugin(false) #if ENABLE(NETSCAPE_PLUGIN_API) , m_windowScriptNPObject(0) #endif @@ -96,14 +96,16 @@ ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode) JSLock lock(false); - // Evaluating the JavaScript could cause the frame to be deallocated - // so we start the keep alive timer here. - m_frame->keepAlive(); + RefPtr<Frame> protect = m_frame; m_windowShell->window()->globalData()->timeoutChecker.start(); Completion comp = JSC::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(), jsSourceCode, m_windowShell); m_windowShell->window()->globalData()->timeoutChecker.stop(); + // Evaluating the JavaScript could cause the frame to be deallocated + // so we start the keep alive timer here. + m_frame->keepAlive(); + if (comp.complType() == Normal || comp.complType() == ReturnValue) { m_sourceURL = savedSourceURL; return comp.value(); @@ -113,7 +115,7 @@ ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode) reportException(exec, comp.value()); m_sourceURL = savedSourceURL; - return noValue(); + return JSValue(); } void ScriptController::clearWindowShell() @@ -122,9 +124,13 @@ void ScriptController::clearWindowShell() return; JSLock lock(false); - m_windowShell->window()->clear(); - m_liveFormerWindows.add(m_windowShell->window()); + + // Clear the debugger from the current window before setting the new window. + attachDebugger(0); + + m_windowShell->window()->willRemoveFromWindowShell(); m_windowShell->setWindow(m_frame->domWindow()); + if (Page* page = m_frame->page()) { attachDebugger(page->debugger()); m_windowShell->window()->setProfileGroup(page->group().identifier()); @@ -134,24 +140,6 @@ void ScriptController::clearWindowShell() gcController().garbageCollectSoon(); } -PassRefPtr<EventListener> ScriptController::createInlineEventListener(const String& functionName, const String& code, Node* node) -{ - initScriptIfNeeded(); - JSLock lock(false); - return JSLazyEventListener::create(JSLazyEventListener::HTMLLazyEventListener, functionName, code, m_windowShell->window(), node, m_handlerLineno); -} - -#if ENABLE(SVG) - -PassRefPtr<EventListener> ScriptController::createSVGEventHandler(const String& functionName, const String& code, Node* node) -{ - initScriptIfNeeded(); - JSLock lock(false); - return JSLazyEventListener::create(JSLazyEventListener::SVGLazyEventListener, functionName, code, m_windowShell->window(), node, m_handlerLineno); -} - -#endif - void ScriptController::initScript() { if (m_windowShell) @@ -160,7 +148,7 @@ void ScriptController::initScript() JSLock lock(false); m_windowShell = new JSDOMWindowShell(m_frame->domWindow()); - updateDocument(); + m_windowShell->window()->updateDocument(); if (Page* page = m_frame->page()) { attachDebugger(page->debugger()); @@ -172,7 +160,7 @@ void ScriptController::initScript() bool ScriptController::processingUserGesture() const { - return processingUserGestureEvent() || isJavaScriptAnchorNavigation(); + return m_allowPopupsFromPlugin || processingUserGestureEvent() || isJavaScriptAnchorNavigation(); } bool ScriptController::processingUserGestureEvent() const @@ -257,9 +245,6 @@ void ScriptController::updateDocument() JSLock lock(false); if (m_windowShell) m_windowShell->window()->updateDocument(); - HashSet<JSDOMWindow*>::iterator end = m_liveFormerWindows.end(); - for (HashSet<JSDOMWindow*>::iterator it = m_liveFormerWindows.begin(); it != end; ++it) - (*it)->updateDocument(); } void ScriptController::updateSecurityOrigin() @@ -335,7 +320,7 @@ JSObject* ScriptController::jsObjectForPluginElement(HTMLPlugInElement* plugin) // Create a JSObject bound to this element JSLock lock(false); ExecState* exec = globalObject()->globalExec(); - JSValuePtr jsElementValue = toJS(exec, plugin); + JSValue jsElementValue = toJS(exec, plugin); if (!jsElementValue || !jsElementValue.isObject()) return 0; diff --git a/WebCore/bindings/js/ScriptController.h b/WebCore/bindings/js/ScriptController.h index 6f1781e..f700cd9 100644 --- a/WebCore/bindings/js/ScriptController.h +++ b/WebCore/bindings/js/ScriptController.h @@ -81,11 +81,8 @@ public: ScriptValue evaluate(const ScriptSourceCode&); - PassRefPtr<EventListener> createInlineEventListener(const String& functionName, const String& code, Node*); -#if ENABLE(SVG) - PassRefPtr<EventListener> createSVGEventHandler(const String& functionName, const String& code, Node*); -#endif - void setEventHandlerLineno(int lineno) { m_handlerLineno = lineno; } + void setEventHandlerLineNumber(int lineno) { m_handlerLineNumber = lineno; } + int eventHandlerLineNumber() { return m_handlerLineNumber; } void setProcessingTimerCallback(bool b) { m_processingTimerCallback = b; } bool processingUserGesture() const; @@ -98,10 +95,12 @@ public: void setPaused(bool b) { m_paused = b; } bool isPaused() const { return m_paused; } + void setAllowPopupsFromPlugin(bool allowPopupsFromPlugin) { m_allowPopupsFromPlugin = allowPopupsFromPlugin; } + bool allowPopupsFromPlugin() const { return m_allowPopupsFromPlugin; } + const String* sourceURL() const { return m_sourceURL; } // 0 if we are not evaluating any script void clearWindowShell(); - void clearFormerWindow(JSDOMWindow* window) { m_liveFormerWindows.remove(window); } void updateDocument(); // Notifies the ScriptController that the securityOrigin of the current @@ -148,13 +147,13 @@ private: bool isJavaScriptAnchorNavigation() const; JSC::ProtectedPtr<JSDOMWindowShell> m_windowShell; - HashSet<JSDOMWindow*> m_liveFormerWindows; Frame* m_frame; - int m_handlerLineno; + int m_handlerLineNumber; const String* m_sourceURL; bool m_processingTimerCallback; bool m_paused; + bool m_allowPopupsFromPlugin; // The root object used for objects bound outside the context of a plugin. RefPtr<JSC::Bindings::RootObject> m_bindingRootObject; diff --git a/WebCore/bindings/js/ScriptControllerMac.mm b/WebCore/bindings/js/ScriptControllerMac.mm index 6554e11..502a504 100644 --- a/WebCore/bindings/js/ScriptControllerMac.mm +++ b/WebCore/bindings/js/ScriptControllerMac.mm @@ -141,7 +141,7 @@ void ScriptController::disconnectPlatformScriptObjects() static pthread_t mainThread; -static void updateRenderingForBindings(JSC::ExecState*, JSC::JSObject* rootObject) +static void updateStyleIfNeededForBindings(JSC::ExecState*, JSC::JSObject* rootObject) { if (pthread_self() != mainThread) return; @@ -157,14 +157,14 @@ static void updateRenderingForBindings(JSC::ExecState*, JSC::JSObject* rootObjec if (!frame) return; - frame->document()->updateRendering(); + frame->document()->updateStyleIfNeeded(); } void ScriptController::initJavaJSBindings() { mainThread = pthread_self(); JSC::Bindings::JavaJSObject::initializeJNIThreading(); - JSC::Bindings::Instance::setDidExecuteFunction(updateRenderingForBindings); + JSC::Bindings::Instance::setDidExecuteFunction(updateStyleIfNeededForBindings); } #endif diff --git a/WebCore/bindings/js/ScriptEventListener.cpp b/WebCore/bindings/js/ScriptEventListener.cpp new file mode 100644 index 0000000..0ce7bca --- /dev/null +++ b/WebCore/bindings/js/ScriptEventListener.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "ScriptEventListener.h" + +#include "Attribute.h" +#include "Document.h" +#include "JSNode.h" +#include "Frame.h" + +#include <runtime/JSLock.h> + +using namespace JSC; + +namespace WebCore { + +static const String& eventParameterName(bool isSVGEvent) +{ + DEFINE_STATIC_LOCAL(const String, eventString, ("event")); + DEFINE_STATIC_LOCAL(const String, evtString, ("evt")); + return isSVGEvent ? evtString : eventString; +} + +PassRefPtr<JSLazyEventListener> createAttributeEventListener(Node* node, Attribute* attr) +{ + ASSERT(node); + + Frame* frame = node->document()->frame(); + if (!frame) + return 0; + + ScriptController* scriptController = frame->script(); + if (!scriptController->isEnabled()) + return 0; + + JSDOMWindow* globalObject = scriptController->globalObject(); + + // Ensure that 'node' has a JavaScript wrapper to mark the event listener we're creating. + { + JSLock lock(false); + toJS(globalObject->globalExec(), node); + } + + return JSLazyEventListener::create(attr->localName().string(), eventParameterName(node->isSVGElement()), attr->value(), globalObject, node, scriptController->eventHandlerLineNumber()); +} + +PassRefPtr<JSLazyEventListener> createAttributeEventListener(Frame* frame, Attribute* attr) +{ + if (!frame) + return 0; + + ScriptController* scriptController = frame->script(); + if (!scriptController->isEnabled()) + return 0; + + // 'globalObject' is the JavaScript wrapper that will mark the event listener we're creating. + JSDOMWindow* globalObject = scriptController->globalObject(); + + return JSLazyEventListener::create(attr->localName().string(), eventParameterName(frame->document()->isSVGDocument()), attr->value(), globalObject, 0, scriptController->eventHandlerLineNumber()); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/V8XMLHttpRequestUtilities.h b/WebCore/bindings/js/ScriptEventListener.h index 5a55974..8299d29 100644 --- a/WebCore/bindings/v8/V8XMLHttpRequestUtilities.h +++ b/WebCore/bindings/js/ScriptEventListener.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2009 Google Inc. All rights reserved. + * Copyright (C) 2009 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,18 +28,22 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef V8XMLHttpRequestUtilities_h -#define V8XMLHttpRequestUtilities_h +#ifndef ScriptEventListener_h +#define ScriptEventListener_h -#include <v8.h> +#include "JSLazyEventListener.h" + +#include <wtf/PassRefPtr.h> namespace WebCore { -// Use an array to hold dependents. It works like a ref-counted scheme. -// A value can be added more than once to the xmlHttpRequest object. -void createHiddenXHRDependency(v8::Local<v8::Object> xmlHttpRequest, v8::Local<v8::Value>); -void removeHiddenXHRDependency(v8::Local<v8::Object> xmlHttpRequest, v8::Local<v8::Value>); + class Attribute; + class Frame; + class Node; + + PassRefPtr<JSLazyEventListener> createAttributeEventListener(Node*, Attribute*); + PassRefPtr<JSLazyEventListener> createAttributeEventListener(Frame*, Attribute*); } // namespace WebCore -#endif // V8XMLHttpRequestUtilities_h +#endif // ScriptEventListener_h diff --git a/WebCore/bindings/js/ScriptFunctionCall.cpp b/WebCore/bindings/js/ScriptFunctionCall.cpp index 5d928c1..1122931 100644 --- a/WebCore/bindings/js/ScriptFunctionCall.cpp +++ b/WebCore/bindings/js/ScriptFunctionCall.cpp @@ -34,13 +34,15 @@ #include "JSDOMBinding.h" #include "ScriptString.h" #include "ScriptValue.h" + #include <runtime/JSLock.h> +#include <runtime/UString.h> using namespace JSC; namespace WebCore { -ScriptFunctionCall::ScriptFunctionCall(ScriptState* exec, const ScriptObject& thisObject, const char* name) +ScriptFunctionCall::ScriptFunctionCall(ScriptState* exec, const ScriptObject& thisObject, const String& name) : m_exec(exec) , m_thisObject(thisObject) , m_name(name) @@ -68,26 +70,50 @@ void ScriptFunctionCall::appendArgument(const String& argument) m_arguments.append(jsString(m_exec, argument)); } +void ScriptFunctionCall::appendArgument(const JSC::UString& argument) +{ + m_arguments.append(jsString(m_exec, argument)); +} + +void ScriptFunctionCall::appendArgument(JSC::JSValue argument) +{ + m_arguments.append(argument); +} + +void ScriptFunctionCall::appendArgument(long long argument) +{ + JSLock lock(false); + m_arguments.append(jsNumber(m_exec, argument)); +} + void ScriptFunctionCall::appendArgument(unsigned int argument) { JSLock lock(false); m_arguments.append(jsNumber(m_exec, argument)); } +void ScriptFunctionCall::appendArgument(int argument) +{ + JSLock lock(false); + m_arguments.append(jsNumber(m_exec, argument)); +} + void ScriptFunctionCall::appendArgument(bool argument) { m_arguments.append(jsBoolean(argument)); } -ScriptValue ScriptFunctionCall::call(bool& hadException) +ScriptValue ScriptFunctionCall::call(bool& hadException, bool reportExceptions) { JSObject* thisObject = m_thisObject.jsObject(); JSLock lock(false); - JSValuePtr function = thisObject->get(m_exec, Identifier(m_exec, m_name)); + JSValue function = thisObject->get(m_exec, Identifier(m_exec, m_name)); if (m_exec->hadException()) { - reportException(m_exec, m_exec->exception()); + if (reportExceptions) + reportException(m_exec, m_exec->exception()); + hadException = true; return ScriptValue(); } @@ -97,9 +123,11 @@ ScriptValue ScriptFunctionCall::call(bool& hadException) if (callType == CallTypeNone) return ScriptValue(); - JSValuePtr result = JSC::call(m_exec, function, callType, callData, thisObject, m_arguments); + JSValue result = JSC::call(m_exec, function, callType, callData, thisObject, m_arguments); if (m_exec->hadException()) { - reportException(m_exec, m_exec->exception()); + if (reportExceptions) + reportException(m_exec, m_exec->exception()); + hadException = true; return ScriptValue(); } @@ -107,7 +135,13 @@ ScriptValue ScriptFunctionCall::call(bool& hadException) return ScriptValue(result); } -ScriptObject ScriptFunctionCall::construct(bool& hadException) +ScriptValue ScriptFunctionCall::call() +{ + bool hadException = false; + return call(hadException); +} + +ScriptObject ScriptFunctionCall::construct(bool& hadException, bool reportExceptions) { JSObject* thisObject = m_thisObject.jsObject(); @@ -115,7 +149,9 @@ ScriptObject ScriptFunctionCall::construct(bool& hadException) JSObject* constructor = asObject(thisObject->get(m_exec, Identifier(m_exec, m_name))); if (m_exec->hadException()) { - reportException(m_exec, m_exec->exception()); + if (reportExceptions) + reportException(m_exec, m_exec->exception()); + hadException = true; return ScriptObject(); } @@ -125,9 +161,11 @@ ScriptObject ScriptFunctionCall::construct(bool& hadException) if (constructType == ConstructTypeNone) return ScriptObject(); - JSValuePtr result = JSC::construct(m_exec, constructor, constructType, constructData, m_arguments); + JSValue result = JSC::construct(m_exec, constructor, constructType, constructData, m_arguments); if (m_exec->hadException()) { - reportException(m_exec, m_exec->exception()); + if (reportExceptions) + reportException(m_exec, m_exec->exception()); + hadException = true; return ScriptObject(); } diff --git a/WebCore/bindings/js/ScriptFunctionCall.h b/WebCore/bindings/js/ScriptFunctionCall.h index 0b01717..079ac21 100644 --- a/WebCore/bindings/js/ScriptFunctionCall.h +++ b/WebCore/bindings/js/ScriptFunctionCall.h @@ -37,30 +37,39 @@ #include <runtime/ArgList.h> +namespace JSC { + class UString; + class JSValue; +} + namespace WebCore { class ScriptValue; class ScriptString; class ScriptFunctionCall { public: - ScriptFunctionCall(ScriptState* exec, const ScriptObject& thisObject, const char* name); + ScriptFunctionCall(ScriptState* exec, const ScriptObject& thisObject, const String& name); virtual ~ScriptFunctionCall() {}; void appendArgument(const ScriptObject&); void appendArgument(const ScriptString&); void appendArgument(const ScriptValue&); void appendArgument(const String&); + void appendArgument(const JSC::UString&); + void appendArgument(JSC::JSValue); + void appendArgument(long long); void appendArgument(unsigned int); + void appendArgument(int); void appendArgument(bool); - ScriptValue call(bool& hadException); - ScriptObject construct(bool& hadException); + ScriptValue call(bool& hadException, bool reportExceptions = true); + ScriptValue call(); + ScriptObject construct(bool& hadException, bool reportExceptions = true); protected: ScriptState* m_exec; ScriptObject m_thisObject; String m_name; - JSC::ArgList m_arguments; - bool m_quarantineObjects; + JSC::MarkedArgumentBuffer m_arguments; }; } // namespace WebCore diff --git a/WebCore/bindings/js/ScriptObject.cpp b/WebCore/bindings/js/ScriptObject.cpp index 148dac5..44337bd 100644 --- a/WebCore/bindings/js/ScriptObject.cpp +++ b/WebCore/bindings/js/ScriptObject.cpp @@ -31,6 +31,14 @@ #include "config.h" #include "ScriptObject.h" +#include "JSDOMBinding.h" + +#if ENABLE(JAVASCRIPT_DEBUGGER) +#include "JSInspectorController.h" +#endif + +#include <runtime/JSLock.h> + using namespace JSC; namespace WebCore { @@ -40,4 +48,112 @@ ScriptObject::ScriptObject(JSObject* object) { } +static bool handleException(ScriptState* scriptState) +{ + if (!scriptState->hadException()) + return true; + + reportException(scriptState, scriptState->exception()); + return false; +} + +bool ScriptObject::set(ScriptState* scriptState, const String& name, const String& value) +{ + JSLock lock(false); + PutPropertySlot slot; + jsObject()->put(scriptState, Identifier(scriptState, name), jsString(scriptState, value), slot); + return handleException(scriptState); +} + +bool ScriptObject::set(ScriptState* scriptState, const char* name, const ScriptObject& value) +{ + JSLock lock(false); + PutPropertySlot slot; + jsObject()->put(scriptState, Identifier(scriptState, name), value.jsObject(), slot); + return handleException(scriptState); +} + +bool ScriptObject::set(ScriptState* scriptState, const char* name, const String& value) +{ + JSLock lock(false); + PutPropertySlot slot; + jsObject()->put(scriptState, Identifier(scriptState, name), jsString(scriptState, value), slot); + return handleException(scriptState); +} + +bool ScriptObject::set(ScriptState* scriptState, const char* name, double value) +{ + JSLock lock(false); + PutPropertySlot slot; + jsObject()->put(scriptState, Identifier(scriptState, name), jsNumber(scriptState, value), slot); + return handleException(scriptState); +} + +bool ScriptObject::set(ScriptState* scriptState, const char* name, long long value) +{ + JSLock lock(false); + PutPropertySlot slot; + jsObject()->put(scriptState, Identifier(scriptState, name), jsNumber(scriptState, value), slot); + return handleException(scriptState); +} + +bool ScriptObject::set(ScriptState* scriptState, const char* name, int value) +{ + JSLock lock(false); + PutPropertySlot slot; + jsObject()->put(scriptState, Identifier(scriptState, name), jsNumber(scriptState, value), slot); + return handleException(scriptState); +} + +bool ScriptObject::set(ScriptState* scriptState, const char* name, bool value) +{ + JSLock lock(false); + PutPropertySlot slot; + jsObject()->put(scriptState, Identifier(scriptState, name), jsBoolean(value), slot); + return handleException(scriptState); +} + +ScriptObject ScriptObject::createNew(ScriptState* scriptState) +{ + JSLock lock(false); + return ScriptObject(constructEmptyObject(scriptState)); +} + +bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, const ScriptObject& value) +{ + JSLock lock(false); + scriptState->lexicalGlobalObject()->putDirect(Identifier(scriptState, name), value.jsObject()); + return handleException(scriptState); +} + +#if ENABLE(JAVASCRIPT_DEBUGGER) +bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InspectorController* value) +{ + JSLock lock(false); + scriptState->lexicalGlobalObject()->putDirect(Identifier(scriptState, name), toJS(scriptState, value)); + return handleException(scriptState); +} +#endif + +bool ScriptGlobalObject::get(ScriptState* scriptState, const char* name, ScriptObject& value) +{ + JSLock lock(false); + JSValue jsValue = scriptState->lexicalGlobalObject()->get(scriptState, Identifier(scriptState, name)); + if (!jsValue) + return false; + + if (!jsValue.isObject()) + return false; + + value = ScriptObject(asObject(jsValue)); + return true; +} + +bool ScriptGlobalObject::remove(ScriptState* scriptState, const char* name) +{ + JSLock lock(false); + scriptState->lexicalGlobalObject()->deleteProperty(scriptState, Identifier(scriptState, name)); + return handleException(scriptState); +} + } // namespace WebCore diff --git a/WebCore/bindings/js/ScriptObject.h b/WebCore/bindings/js/ScriptObject.h index 08fa323..ed86659 100644 --- a/WebCore/bindings/js/ScriptObject.h +++ b/WebCore/bindings/js/ScriptObject.h @@ -31,18 +31,40 @@ #ifndef ScriptObject_h #define ScriptObject_h +#include "ScriptState.h" #include "ScriptValue.h" #include <runtime/JSObject.h> #include <runtime/Protect.h> namespace WebCore { + class InspectorController; class ScriptObject : public ScriptValue { public: ScriptObject(JSC::JSObject*); ScriptObject() {} JSC::JSObject* jsObject() const { return asObject(jsValue()); } + + bool set(ScriptState*, const String& name, const String&); + bool set(ScriptState*, const char* name, const ScriptObject&); + bool set(ScriptState*, const char* name, const String&); + bool set(ScriptState*, const char* name, double); + bool set(ScriptState*, const char* name, long long); + bool set(ScriptState*, const char* name, int); + bool set(ScriptState*, const char* name, bool); + + static ScriptObject createNew(ScriptState*); + }; + + class ScriptGlobalObject { + public: + static bool set(ScriptState*, const char* name, const ScriptObject&); + static bool set(ScriptState*, const char* name, InspectorController*); + static bool get(ScriptState*, const char* name, ScriptObject&); + static bool remove(ScriptState*, const char* name); + private: + ScriptGlobalObject() { } }; } diff --git a/WebCore/bindings/js/ScriptObjectQuarantine.cpp b/WebCore/bindings/js/ScriptObjectQuarantine.cpp index 9311737..13e180a 100644 --- a/WebCore/bindings/js/ScriptObjectQuarantine.cpp +++ b/WebCore/bindings/js/ScriptObjectQuarantine.cpp @@ -34,15 +34,22 @@ #include "Database.h" #include "Document.h" #include "Frame.h" -#include "JSDatabase.h" -#include "JSStorage.h" #include "JSDOMBinding.h" #include "JSInspectedObjectWrapper.h" +#include "JSNode.h" #include "ScriptObject.h" #include "ScriptValue.h" #include <runtime/JSLock.h> +#if ENABLE(DATABASE) +#include "JSDatabase.h" +#endif + +#if ENABLE(DOM_STORAGE) +#include "JSStorage.h" +#endif + using namespace JSC; namespace WebCore { @@ -53,6 +60,7 @@ ScriptValue quarantineValue(ScriptState* scriptState, const ScriptValue& value) return ScriptValue(JSInspectedObjectWrapper::wrap(scriptState, value.jsValue())); } +#if ENABLE(DATABASE) bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObject) { ASSERT(database); @@ -68,7 +76,9 @@ bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObj return true; } +#endif +#if ENABLE(DOM_STORAGE) bool getQuarantinedScriptObject(Frame* frame, Storage* storage, ScriptObject& quarantinedObject) { ASSERT(frame); @@ -81,5 +91,32 @@ bool getQuarantinedScriptObject(Frame* frame, Storage* storage, ScriptObject& qu return true; } +#endif + +bool getQuarantinedScriptObject(Node* node, ScriptObject& quarantinedObject) +{ + ExecState* exec = scriptStateFromNode(node); + if (!exec) + return false; + + JSLock lock(false); + quarantinedObject = ScriptObject(asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, node)))); + + return true; +} + +bool getQuarantinedScriptObject(DOMWindow* domWindow, ScriptObject& quarantinedObject) +{ + ASSERT(domWindow); + + JSDOMWindow* window = toJSDOMWindow(domWindow->frame()); + ExecState* exec = window->globalExec(); + + JSLock lock(false); + quarantinedObject = ScriptObject(asObject(JSInspectedObjectWrapper::wrap(exec, window))); + + return true; +} + } // namespace WebCore diff --git a/WebCore/bindings/js/ScriptObjectQuarantine.h b/WebCore/bindings/js/ScriptObjectQuarantine.h index a3ac7f1..d70acd7 100644 --- a/WebCore/bindings/js/ScriptObjectQuarantine.h +++ b/WebCore/bindings/js/ScriptObjectQuarantine.h @@ -36,15 +36,23 @@ namespace WebCore { class Database; + class DOMWindow; class Frame; + class Node; class ScriptObject; class ScriptValue; class Storage; ScriptValue quarantineValue(ScriptState*, const ScriptValue&); +#if ENABLE(DATABASE) bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObject); +#endif +#if ENABLE(DOM_STORAGE) bool getQuarantinedScriptObject(Frame* frame, Storage* storage, ScriptObject& quarantinedObject); +#endif + bool getQuarantinedScriptObject(Node* node, ScriptObject& quarantinedObject); + bool getQuarantinedScriptObject(DOMWindow* domWindow, ScriptObject& quarantinedObject); } diff --git a/WebCore/bindings/js/ScriptState.cpp b/WebCore/bindings/js/ScriptState.cpp new file mode 100644 index 0000000..8bfa33d --- /dev/null +++ b/WebCore/bindings/js/ScriptState.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "ScriptState.h" + +#include "Frame.h" +#include "Node.h" +#include "Page.h" + +namespace WebCore { + +ScriptState* scriptStateFromNode(Node* node) +{ + if (!node) + return 0; + Document* document = node->document(); + if (!document) + return 0; + Frame* frame = document->frame(); + if (!frame) + return 0; + if (!frame->script()->isEnabled()) + return 0; + return frame->script()->globalObject()->globalExec(); +} + +ScriptState* scriptStateFromPage(Page* page) +{ + return page->mainFrame()->script()->globalObject()->globalExec(); +} + +} diff --git a/WebCore/bindings/js/ScriptState.h b/WebCore/bindings/js/ScriptState.h index 3cce093..fa5c4a8 100644 --- a/WebCore/bindings/js/ScriptState.h +++ b/WebCore/bindings/js/ScriptState.h @@ -32,11 +32,11 @@ #ifndef ScriptState_h #define ScriptState_h -namespace JSC { - class ExecState; -} +#include "JSDOMBinding.h" namespace WebCore { + class Node; + class Page; // The idea is to expose "state-like" methods (hadException, and any other // methods where ExecState just dips into globalData) of JSC::ExecState as a @@ -44,6 +44,9 @@ namespace WebCore { // For now, the separation is purely by convention. typedef JSC::ExecState ScriptState; + ScriptState* scriptStateFromNode(Node*); + ScriptState* scriptStateFromPage(Page*); + } // namespace WebCore #endif // ScriptState_h diff --git a/WebCore/bindings/js/ScriptValue.cpp b/WebCore/bindings/js/ScriptValue.cpp index c4a7579..dfb46da 100644 --- a/WebCore/bindings/js/ScriptValue.cpp +++ b/WebCore/bindings/js/ScriptValue.cpp @@ -57,7 +57,7 @@ bool ScriptValue::isEqual(ScriptState* scriptState, const ScriptValue& anotherVa if (hasNoValue()) return anotherValue.hasNoValue(); - return JSValueIsEqual(toRef(scriptState), toRef(jsValue()), toRef(anotherValue.jsValue()), 0); + return JSValueIsEqual(toRef(scriptState), toRef(scriptState, jsValue()), toRef(scriptState, anotherValue.jsValue()), 0); } bool ScriptValue::isNull() const diff --git a/WebCore/bindings/js/ScriptValue.h b/WebCore/bindings/js/ScriptValue.h index e6e7cb1..209ce06 100644 --- a/WebCore/bindings/js/ScriptValue.h +++ b/WebCore/bindings/js/ScriptValue.h @@ -41,19 +41,19 @@ class String; class ScriptValue { public: - ScriptValue(JSC::JSValuePtr value = JSC::noValue()) : m_value(value) {} + ScriptValue(JSC::JSValue value = JSC::JSValue()) : m_value(value) {} virtual ~ScriptValue() {} - JSC::JSValuePtr jsValue() const { return m_value.get(); } + JSC::JSValue jsValue() const { return m_value.get(); } bool getString(String& result) const; String toString(ScriptState* scriptState) const { return m_value.get().toString(scriptState); } bool isEqual(ScriptState*, const ScriptValue&) const; bool isNull() const; bool isUndefined() const; - bool hasNoValue() const { return m_value == JSC::noValue(); } + bool hasNoValue() const { return m_value == JSC::JSValue(); } private: - JSC::ProtectedJSValuePtr m_value; + JSC::ProtectedJSValue m_value; }; } // namespace WebCore diff --git a/WebCore/bindings/js/WorkerScriptController.cpp b/WebCore/bindings/js/WorkerScriptController.cpp index 25d7eb9..bcf107b 100644 --- a/WebCore/bindings/js/WorkerScriptController.cpp +++ b/WebCore/bindings/js/WorkerScriptController.cpp @@ -83,7 +83,7 @@ ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode) { MutexLocker lock(m_sharedDataMutex); if (m_executionForbidden) - return noValue(); + return JSValue(); } ScriptValue exception; ScriptValue result = evaluate(sourceCode, &exception); @@ -99,7 +99,7 @@ ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, { MutexLocker lock(m_sharedDataMutex); if (m_executionForbidden) - return noValue(); + return JSValue(); } initScriptIfNeeded(); @@ -110,14 +110,14 @@ ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, Completion comp = JSC::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(), sourceCode.jsSourceCode(), m_workerContextWrapper); m_workerContextWrapper->globalData()->timeoutChecker.stop(); - m_workerContext->thread()->workerObjectProxy()->reportPendingActivity(m_workerContext->hasPendingActivity()); + m_workerContext->thread()->workerObjectProxy().reportPendingActivity(m_workerContext->hasPendingActivity()); if (comp.complType() == Normal || comp.complType() == ReturnValue) return comp.value(); if (comp.complType() == Throw) *exception = comp.value(); - return noValue(); + return JSValue(); } void WorkerScriptController::setException(ScriptValue exception) diff --git a/WebCore/bindings/objc/DOM.mm b/WebCore/bindings/objc/DOM.mm index 53be4ff..3fd28d1 100644 --- a/WebCore/bindings/objc/DOM.mm +++ b/WebCore/bindings/objc/DOM.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2006 James G. Speth (speth@end.com) * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) * @@ -26,34 +26,32 @@ */ #import "config.h" +#import "DOMInternal.h" // import first to make the private/public trick work #import "DOM.h" +#import "DOMRangeInternal.h" +#import "DOMElementInternal.h" +#import "DOMNodeInternal.h" #import "DOMHTMLCanvasElement.h" -#import "DOMInternal.h" -#import "ExceptionHandlers.h" #import "Frame.h" #import "HTMLNames.h" -#import "HTMLPlugInElement.h" -#import "NodeIterator.h" -#import "Range.h" +#import "HTMLElement.h" #import "RenderImage.h" -#import "RenderView.h" -#import "ScriptController.h" -#import "SimpleFontData.h" -#import "TreeWalker.h" - +#import "NodeFilter.h" +#import "WebScriptObjectPrivate.h" #import <wtf/HashMap.h> -#if ENABLE(SVG) -#import "SVGElement.h" -#import "SVGElementInstance.h" -#import "SVGNames.h" +#if ENABLE(SVG_DOM_OBJC_BINDINGS) #import "DOMSVG.h" +#import "SVGElementInstance.h" #endif using namespace JSC; using namespace WebCore; +// FIXME: Would be nice to break this up into separate files to match how other WebKit +// code is organized. + //------------------------------------------------------------------------------------------ // DOMNode @@ -144,7 +142,7 @@ static void createElementClassMap() addElementClass(HTMLNames::ulTag, [DOMHTMLUListElement class]); addElementClass(HTMLNames::xmpTag, [DOMHTMLPreElement class]); -#if ENABLE(SVG) +#if ENABLE(SVG_DOM_OBJC_BINDINGS) addElementClass(SVGNames::aTag, [DOMSVGAElement class]); addElementClass(SVGNames::altGlyphTag, [DOMSVGAltGlyphElement class]); #if ENABLE(SVG_ANIMATION) @@ -162,7 +160,7 @@ static void createElementClassMap() addElementClass(SVGNames::defsTag, [DOMSVGDefsElement class]); addElementClass(SVGNames::descTag, [DOMSVGDescElement class]); addElementClass(SVGNames::ellipseTag, [DOMSVGEllipseElement class]); -#if ENABLE(SVG_FILTERS) +#if ENABLE(FILTERS) addElementClass(SVGNames::feBlendTag, [DOMSVGFEBlendElement class]); addElementClass(SVGNames::feColorMatrixTag, [DOMSVGFEColorMatrixElement class]); addElementClass(SVGNames::feComponentTransferTag, [DOMSVGFEComponentTransferElement class]); @@ -260,7 +258,6 @@ static NSArray *kit(const Vector<IntRect>& rects) @implementation DOMNode (WebCoreInternal) -// FIXME: should this go in the main implementation? - (NSString *)description { if (!_internal) @@ -274,192 +271,125 @@ static NSArray *kit(const Vector<IntRect>& rects) return [NSString stringWithFormat:@"<%@ [%@]: %p>", [[self class] description], [self nodeName], _internal]; } -- (id)_initWithNode:(WebCore::Node *)impl +- (JSC::Bindings::RootObject*)_rootObject { - ASSERT(impl); - - [super _init]; - _internal = reinterpret_cast<DOMObjectInternal*>(impl); - impl->ref(); - WebCore::addDOMWrapper(self, impl); - return self; + WebCore::Frame* frame = core(self)->document()->frame(); + if (!frame) + return 0; + return frame->script()->bindingRootObject(); } -+ (DOMNode *)_wrapNode:(WebCore::Node *)impl -{ - if (!impl) - return nil; - - id cachedInstance; - cachedInstance = WebCore::getDOMWrapper(impl); - if (cachedInstance) - return [[cachedInstance retain] autorelease]; +@end - Class wrapperClass = nil; +Class kitClass(WebCore::Node* impl) +{ switch (impl->nodeType()) { case WebCore::Node::ELEMENT_NODE: if (impl->isHTMLElement()) - wrapperClass = WebCore::elementClass(static_cast<WebCore::HTMLElement*>(impl)->tagQName(), [DOMHTMLElement class]); -#if ENABLE(SVG) - else if (impl->isSVGElement()) - wrapperClass = WebCore::elementClass(static_cast<WebCore::SVGElement*>(impl)->tagQName(), [DOMSVGElement class]); + return WebCore::elementClass(static_cast<WebCore::HTMLElement*>(impl)->tagQName(), [DOMHTMLElement class]); +#if ENABLE(SVG_DOM_OBJC_BINDINGS) + if (impl->isSVGElement()) + return WebCore::elementClass(static_cast<WebCore::SVGElement*>(impl)->tagQName(), [DOMSVGElement class]); #endif - else - wrapperClass = [DOMElement class]; - break; + return [DOMElement class]; case WebCore::Node::ATTRIBUTE_NODE: - wrapperClass = [DOMAttr class]; - break; + return [DOMAttr class]; case WebCore::Node::TEXT_NODE: - wrapperClass = [DOMText class]; - break; + return [DOMText class]; case WebCore::Node::CDATA_SECTION_NODE: - wrapperClass = [DOMCDATASection class]; - break; + return [DOMCDATASection class]; case WebCore::Node::ENTITY_REFERENCE_NODE: - wrapperClass = [DOMEntityReference class]; - break; + return [DOMEntityReference class]; case WebCore::Node::ENTITY_NODE: - wrapperClass = [DOMEntity class]; - break; + return [DOMEntity class]; case WebCore::Node::PROCESSING_INSTRUCTION_NODE: - wrapperClass = [DOMProcessingInstruction class]; - break; + return [DOMProcessingInstruction class]; case WebCore::Node::COMMENT_NODE: - wrapperClass = [DOMComment class]; - break; + return [DOMComment class]; case WebCore::Node::DOCUMENT_NODE: if (static_cast<WebCore::Document*>(impl)->isHTMLDocument()) - wrapperClass = [DOMHTMLDocument class]; -#if ENABLE(SVG) - else if (static_cast<WebCore::Document*>(impl)->isSVGDocument()) - wrapperClass = [DOMSVGDocument class]; + return [DOMHTMLDocument class]; +#if ENABLE(SVG_DOM_OBJC_BINDINGS) + if (static_cast<WebCore::Document*>(impl)->isSVGDocument()) + return [DOMSVGDocument class]; #endif - else - wrapperClass = [DOMDocument class]; - break; + return [DOMDocument class]; case WebCore::Node::DOCUMENT_TYPE_NODE: - wrapperClass = [DOMDocumentType class]; - break; + return [DOMDocumentType class]; case WebCore::Node::DOCUMENT_FRAGMENT_NODE: - wrapperClass = [DOMDocumentFragment class]; - break; + return [DOMDocumentFragment class]; case WebCore::Node::NOTATION_NODE: - wrapperClass = [DOMNotation class]; - break; + return [DOMNotation class]; case WebCore::Node::XPATH_NAMESPACE_NODE: // FIXME: Create an XPath objective C wrapper // See http://bugs.webkit.org/show_bug.cgi?id=8755 return nil; } - return [[[wrapperClass alloc] _initWithNode:impl] autorelease]; + ASSERT_NOT_REACHED(); + return nil; } -+ (id <DOMEventTarget>)_wrapEventTarget:(WebCore::EventTarget *)eventTarget +id <DOMEventTarget> kit(WebCore::EventTarget* eventTarget) { if (!eventTarget) return nil; - // We don't have an ObjC binding for XMLHttpRequest - return [DOMNode _wrapNode:eventTarget->toNode()]; -} + if (WebCore::Node* node = eventTarget->toNode()) + return kit(node); -- (WebCore::Node *)_node -{ - return reinterpret_cast<WebCore::Node*>(_internal); -} - -- (JSC::Bindings::RootObject*)_rootObject -{ - if (WebCore::Node *n = [self _node]) { - if (WebCore::Frame* frame = n->document()->frame()) - return frame->script()->bindingRootObject(); - } - return 0; -} - -@end +#if ENABLE(SVG_DOM_OBJC_BINDINGS) + if (WebCore::SVGElementInstance* svgElementInstance = eventTarget->toSVGElementInstance()) + return kit(svgElementInstance); +#endif -@implementation DOMNode (DOMNodeExtensions) + // We don't have an ObjC binding for XMLHttpRequest. -// FIXME: This should be implemented in Node so we don't have to fetch the renderer. -// If it was, we could even autogenerate. -- (NSRect)boundingBox -{ - [self _node]->document()->updateLayoutIgnorePendingStylesheets(); - WebCore::RenderObject *renderer = [self _node]->renderer(); - if (renderer) - return renderer->absoluteBoundingBoxRect(); - return NSZeroRect; -} - -// FIXME: This should be implemented in Node so we don't have to fetch the renderer. -// If it was, we could even autogenerate. -- (NSArray *)lineBoxRects -{ - [self _node]->document()->updateLayoutIgnorePendingStylesheets(); - WebCore::RenderObject *renderer = [self _node]->renderer(); - if (renderer) { - Vector<WebCore::IntRect> rects; - renderer->absoluteRectsForRange(rects); - return kit(rects); - } return nil; } -@end - -#if ENABLE(SVG) -@implementation DOMSVGElementInstance (WebCoreInternal) - -- (id)_initWithSVGElementInstance:(WebCore::SVGElementInstance *)impl -{ - ASSERT(impl); - - [super _init]; - _internal = reinterpret_cast<DOMObjectInternal*>(impl); - impl->ref(); - WebCore::addDOMWrapper(self, impl); - return self; -} +@implementation DOMNode (DOMNodeExtensions) -+ (DOMSVGElementInstance *)_wrapSVGElementInstance:(WebCore::SVGElementInstance *)impl +- (NSRect)boundingBox { - if (!impl) - return nil; - - id cachedInstance; - cachedInstance = WebCore::getDOMWrapper(impl); - if (cachedInstance) - return [[cachedInstance retain] autorelease]; - - return [[[self alloc] _initWithSVGElementInstance:impl] autorelease]; + // FIXME: Could we move this function to WebCore::Node and autogenerate? + core(self)->document()->updateLayoutIgnorePendingStylesheets(); + WebCore::RenderObject* renderer = core(self)->renderer(); + if (!renderer) + return NSZeroRect; + return renderer->absoluteBoundingBoxRect(); } -+ (id <DOMEventTarget>)_wrapEventTarget:(WebCore::EventTarget *)eventTarget +- (NSArray *)textRects { - if (!eventTarget) + // FIXME: Could we move this function to WebCore::Node and autogenerate? + core(self)->document()->updateLayoutIgnorePendingStylesheets(); + if (!core(self)->renderer()) return nil; - - return [DOMSVGElementInstance _wrapSVGElementInstance:eventTarget->toSVGElementInstance()]; + RefPtr<Range> range = Range::create(core(self)->document()); + WebCore::ExceptionCode ec = 0; + range->selectNodeContents(core(self), ec); + Vector<WebCore::IntRect> rects; + range->textRects(rects); + return kit(rects); } -- (WebCore::SVGElementInstance *)_SVGElementInstance +- (NSArray *)lineBoxRects { - return reinterpret_cast<WebCore::SVGElementInstance*>(_internal); + return [self textRects]; } @end -#endif @implementation DOMNode (DOMNodeExtensionsPendingPublic) - (NSImage *)renderedImage { - if (WebCore::Node *node = [self _node]) - if (WebCore::Frame* frame = node->document()->frame()) - return frame->nodeImage(node); - return nil; + // FIXME: Could we move this function to WebCore::Node and autogenerate? + WebCore::Node* node = core(self); + WebCore::Frame* frame = node->document()->frame(); + if (!frame) + return nil; + return frame->nodeImage(node); } @end @@ -468,84 +398,88 @@ static NSArray *kit(const Vector<IntRect>& rects) - (NSRect)boundingBox { - [self _range]->ownerDocument()->updateLayoutIgnorePendingStylesheets(); - return [self _range]->boundingBox(); + // FIXME: The call to updateLayoutIgnorePendingStylesheets should be moved into WebCore::Range. + core(self)->ownerDocument()->updateLayoutIgnorePendingStylesheets(); + return core(self)->boundingBox(); } -- (NSArray *)lineBoxRects +- (NSArray *)textRects { + // FIXME: The call to updateLayoutIgnorePendingStylesheets should be moved into WebCore::Range. Vector<WebCore::IntRect> rects; - [self _range]->ownerDocument()->updateLayoutIgnorePendingStylesheets(); - [self _range]->addLineBoxRects(rects); + core(self)->ownerDocument()->updateLayoutIgnorePendingStylesheets(); + core(self)->textRects(rects); return kit(rects); } +- (NSArray *)lineBoxRects +{ + // FIXME: Remove this once all clients stop using it and we drop Leopard support. + return [self textRects]; +} + @end //------------------------------------------------------------------------------------------ // DOMElement -// FIXME: this should be auto-generated in DOMElement.mm @implementation DOMElement (DOMElementAppKitExtensions) -// FIXME: this should be implemented in the implementation - (NSImage*)image { - WebCore::RenderObject* renderer = [self _element]->renderer(); - if (renderer && renderer->isImage()) { - WebCore::RenderImage* img = static_cast<WebCore::RenderImage*>(renderer); - if (img->cachedImage() && !img->cachedImage()->errorOccurred()) - return img->cachedImage()->image()->getNSImage(); - } - return nil; + // FIXME: Could we move this function to WebCore::Node and autogenerate? + WebCore::RenderObject* renderer = core(self)->renderer(); + if (!renderer || !renderer->isImage()) + return nil; + WebCore::CachedImage* cachedImage = static_cast<WebCore::RenderImage*>(renderer)->cachedImage(); + if (!cachedImage || cachedImage->errorOccurred()) + return nil; + return cachedImage->image()->getNSImage(); } @end @implementation DOMElement (WebPrivate) -// FIXME: this should be implemented in the implementation - (NSFont *)_font { - WebCore::RenderObject* renderer = [self _element]->renderer(); - if (renderer) - return renderer->style()->font().primaryFont()->getNSFont(); - return nil; + // FIXME: Could we move this function to WebCore::Element and autogenerate? + WebCore::RenderObject* renderer = core(self)->renderer(); + if (!renderer) + return nil; + return renderer->style()->font().primaryFont()->getNSFont(); } -// FIXME: this should be implemented in the implementation - (NSData *)_imageTIFFRepresentation { - WebCore::RenderObject* renderer = [self _element]->renderer(); - if (renderer && renderer->isImage()) { - WebCore::RenderImage* img = static_cast<WebCore::RenderImage*>(renderer); - if (img->cachedImage() && !img->cachedImage()->errorOccurred()) - return (NSData*)(img->cachedImage()->image()->getTIFFRepresentation()); - } - return nil; + // FIXME: Could we move this function to WebCore::Element and autogenerate? + WebCore::RenderObject* renderer = core(self)->renderer(); + if (!renderer || !renderer->isImage()) + return nil; + WebCore::CachedImage* cachedImage = static_cast<WebCore::RenderImage*>(renderer)->cachedImage(); + if (!cachedImage || cachedImage->errorOccurred()) + return nil; + return (NSData *)cachedImage->image()->getTIFFRepresentation(); } -// FIXME: this should be implemented in the implementation - (NSURL *)_getURLAttribute:(NSString *)name { + // FIXME: Could we move this function to WebCore::Element and autogenerate? ASSERT(name); - WebCore::Element* element = [self _element]; + WebCore::Element* element = core(self); ASSERT(element); return element->document()->completeURL(parseURL(element->getAttribute(name))); } -// FIXME: this should be implemented in the implementation - (BOOL)isFocused { - WebCore::Element* impl = [self _element]; - if (impl->document()->focusedNode() == impl) - return YES; - return NO; + // FIXME: Could we move this function to WebCore::Element and autogenerate? + WebCore::Element* element = core(self); + return element->document()->focusedNode() == element; } @end - //------------------------------------------------------------------------------------------ // DOMRange @@ -559,7 +493,7 @@ static NSArray *kit(const Vector<IntRect>& rects) [self startContainer], [self startOffset], [self endContainer], [self endOffset]]; } -// FIXME: this should be removed as soon as all internal Apple uses of it have been replaced with +// FIXME: This should be removed as soon as all internal Apple uses of it have been replaced with // calls to the public method - (NSString *)text. - (NSString *)_text { @@ -568,43 +502,31 @@ static NSArray *kit(const Vector<IntRect>& rects) @end - //------------------------------------------------------------------------------------------ // DOMNodeFilter -// FIXME: This implementation should be in it's own file. - -@implementation DOMNodeFilter - -- (id)_initWithNodeFilter:(WebCore::NodeFilter *)impl -{ - ASSERT(impl); - - [super _init]; - _internal = reinterpret_cast<DOMObjectInternal*>(impl); - impl->ref(); - WebCore::addDOMWrapper(self, impl); - return self; -} - -+ (DOMNodeFilter *)_wrapNodeFilter:(WebCore::NodeFilter *)impl +DOMNodeFilter *kit(WebCore::NodeFilter* impl) { if (!impl) return nil; - - id cachedInstance; - cachedInstance = WebCore::getDOMWrapper(impl); - if (cachedInstance) - return [[cachedInstance retain] autorelease]; - - return [[[self alloc] _initWithNodeFilter:impl] autorelease]; + + if (DOMNodeFilter *wrapper = getDOMWrapper(impl)) + return [[wrapper retain] autorelease]; + + DOMNodeFilter *wrapper = [[DOMNodeFilter alloc] _init]; + wrapper->_internal = reinterpret_cast<DOMObjectInternal*>(impl); + impl->ref(); + addDOMWrapper(wrapper, impl); + return [wrapper autorelease]; } -- (WebCore::NodeFilter *)_nodeFilter +WebCore::NodeFilter* core(DOMNodeFilter *wrapper) { - return reinterpret_cast<WebCore::NodeFilter*>(_internal); + return wrapper ? reinterpret_cast<WebCore::NodeFilter*>(wrapper->_internal) : 0; } +@implementation DOMNodeFilter + - (void)dealloc { if (_internal) @@ -621,7 +543,7 @@ static NSArray *kit(const Vector<IntRect>& rects) - (short)acceptNode:(DOMNode *)node { - return [self _nodeFilter]->acceptNode([node _node]); + return core(self)->acceptNode(core(node)); } @end diff --git a/WebCore/bindings/objc/DOMAbstractView.mm b/WebCore/bindings/objc/DOMAbstractView.mm index 7bfe7f1..0b79aa9 100644 --- a/WebCore/bindings/objc/DOMAbstractView.mm +++ b/WebCore/bindings/objc/DOMAbstractView.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,16 +27,14 @@ */ #import "config.h" -#import "DOMAbstractView.h" +#import "DOMInternal.h" // import first to make the private/public trick work +#import "DOMAbstractViewInternal.h" -#import "DOMDocument.h" -#import "DOMInternal.h" -#import "DOMWindow.h" -#import "Document.h" +#import "DOMDocumentInternal.h" #import "ExceptionHandlers.h" #import "Frame.h" #import "ThreadCheck.h" -#import <wtf/GetPtr.h> +#import "WebScriptObjectPrivate.h" #define IMPL reinterpret_cast<WebCore::Frame*>(_internal) @@ -52,7 +50,7 @@ { if (!_internal) return nil; - return [DOMDocument _wrapDocument:WTF::getPtr(IMPL->domWindow()->document())]; + return kit(IMPL->domWindow()->document()); } @end @@ -62,44 +60,34 @@ - (void)_disconnectFrame { ASSERT(_internal); - WebCore::removeDOMWrapper(_internal); + removeDOMWrapper(_internal); _internal = 0; } @end -@implementation DOMAbstractView (WebCoreInternal) - -- (WebCore::DOMWindow *)_abstractView +WebCore::DOMWindow* core(DOMAbstractView *wrapper) { - if (!_internal) - return nil; - return IMPL->domWindow(); + if (!wrapper) + return 0; + if (!wrapper->_internal) + return 0; + return reinterpret_cast<WebCore::Frame*>(wrapper->_internal)->domWindow(); } -- (id)_initWithFrame:(WebCore::Frame *)impl +DOMAbstractView *kit(WebCore::DOMWindow* value) { { DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheckRoundOne(); }; - [super _init]; - _internal = reinterpret_cast<DOMObjectInternal*>(impl); - WebCore::addDOMWrapper(self, impl); - return self; -} -+ (DOMAbstractView *)_wrapAbstractView:(WebCore::DOMWindow *)impl -{ - { DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheckRoundOne(); }; - - if (!impl) + if (!value) return nil; - WebCore::Frame* frame = impl->frame(); + WebCore::Frame* frame = value->frame(); if (!frame) return nil; - id cachedInstance; - cachedInstance = WebCore::getDOMWrapper(frame); - if (cachedInstance) - return [[cachedInstance retain] autorelease]; - return [[[self alloc] _initWithFrame:frame] autorelease]; + if (DOMAbstractView *wrapper = getDOMWrapper(frame)) + return [[wrapper retain] autorelease]; + DOMAbstractView *wrapper = [[DOMAbstractView alloc] _init]; + wrapper->_internal = reinterpret_cast<DOMObjectInternal*>(frame); + addDOMWrapper(wrapper, frame); + return [wrapper autorelease]; } - -@end diff --git a/WebCore/bindings/objc/DOMCSS.mm b/WebCore/bindings/objc/DOMCSS.mm index 4e9cd0c..0149273 100644 --- a/WebCore/bindings/objc/DOMCSS.mm +++ b/WebCore/bindings/objc/DOMCSS.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. * Copyright (C) 2006 James G. Speth (speth@end.com) * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) * @@ -26,194 +26,99 @@ */ #import "config.h" -#import "DOMCSS.h" - -#import "CSSCharsetRule.h" -#import "CSSFontFaceRule.h" -#import "CSSImportRule.h" -#import "CSSMediaRule.h" -#import "CSSPageRule.h" -#import "CSSPrimitiveValue.h" + #import "CSSRule.h" -#import "CSSRuleList.h" -#import "CSSStyleDeclaration.h" -#import "CSSStyleRule.h" -#import "CSSStyleSheet.h" -#import "CSSValueList.h" +#import "CSSValue.h" +#import "DOMCSSCharsetRule.h" +#import "DOMCSSFontFaceRule.h" +#import "DOMCSSImportRule.h" +#import "DOMCSSMediaRule.h" +#import "DOMCSSPageRule.h" +#import "DOMCSSPrimitiveValue.h" +#import "DOMCSSRuleInternal.h" +#import "DOMCSSStyleDeclaration.h" +#import "DOMCSSStyleRule.h" +#import "DOMCSSStyleSheet.h" +#import "DOMCSSUnknownRule.h" +#import "DOMCSSValueInternal.h" +#import "DOMCSSValueList.h" +#import "DOMCSSVariablesRule.h" #import "DOMInternal.h" -#import "DOMPrivate.h" -#import "StyleSheet.h" -#import <objc/objc-class.h> +#import "DOMStyleSheetInternal.h" +#import "DOMWebKitCSSKeyframeRule.h" +#import "DOMWebKitCSSKeyframesRule.h" -#if ENABLE(SVG) -#import "DOMSVGColor.h" +#if ENABLE(SVG_DOM_OBJC_BINDINGS) #import "DOMSVGPaint.h" #endif //------------------------------------------------------------------------------------------ // DOMStyleSheet -@implementation DOMStyleSheet (WebCoreInternal) - -- (WebCore::StyleSheet *)_styleSheet -{ - return reinterpret_cast<WebCore::StyleSheet*>(_internal); -} - -- (id)_initWithStyleSheet:(WebCore::StyleSheet *)impl +Class kitClass(WebCore::StyleSheet* impl) { - [super _init]; - _internal = reinterpret_cast<DOMObjectInternal*>(impl); - impl->ref(); - WebCore::addDOMWrapper(self, impl); - return self; -} - -+ (DOMStyleSheet *)_wrapStyleSheet:(WebCore::StyleSheet *)impl -{ - if (!impl) - return nil; - - id cachedInstance; - cachedInstance = WebCore::getDOMWrapper(impl); - if (cachedInstance) - return [[cachedInstance retain] autorelease]; - - Class wrapperClass; if (impl->isCSSStyleSheet()) - wrapperClass = [DOMCSSStyleSheet class]; - else - wrapperClass = [DOMStyleSheet class]; - return [[[wrapperClass alloc] _initWithStyleSheet:impl] autorelease]; + return [DOMCSSStyleSheet class]; + return [DOMStyleSheet class]; } -@end - //------------------------------------------------------------------------------------------ // DOMCSSRule -@implementation DOMCSSRule (WebCoreInternal) - -- (WebCore::CSSRule *)_CSSRule -{ - return reinterpret_cast<WebCore::CSSRule*>(_internal); -} - -- (id)_initWithCSSRule:(WebCore::CSSRule *)impl -{ - [super _init]; - _internal = reinterpret_cast<DOMObjectInternal*>(impl); - impl->ref(); - WebCore::addDOMWrapper(self, impl); - return self; -} - -+ (DOMCSSRule *)_wrapCSSRule:(WebCore::CSSRule *)impl +Class kitClass(WebCore::CSSRule* impl) { - if (!impl) - return nil; - - id cachedInstance; - cachedInstance = WebCore::getDOMWrapper(impl); - if (cachedInstance) - return [[cachedInstance retain] autorelease]; - - Class wrapperClass = nil; switch (impl->type()) { case DOM_UNKNOWN_RULE: - wrapperClass = [DOMCSSUnknownRule class]; - break; + return [DOMCSSUnknownRule class]; case DOM_STYLE_RULE: - wrapperClass = [DOMCSSStyleRule class]; - break; + return [DOMCSSStyleRule class]; case DOM_CHARSET_RULE: - wrapperClass = [DOMCSSCharsetRule class]; - break; + return [DOMCSSCharsetRule class]; case DOM_IMPORT_RULE: - wrapperClass = [DOMCSSImportRule class]; - break; + return [DOMCSSImportRule class]; case DOM_MEDIA_RULE: - wrapperClass = [DOMCSSMediaRule class]; - break; + return [DOMCSSMediaRule class]; case DOM_FONT_FACE_RULE: - wrapperClass = [DOMCSSFontFaceRule class]; - break; + return [DOMCSSFontFaceRule class]; case DOM_PAGE_RULE: - wrapperClass = [DOMCSSPageRule class]; - break; + return [DOMCSSPageRule class]; case DOM_VARIABLES_RULE: - wrapperClass = [DOMCSSVariablesRule class]; - break; + return [DOMCSSVariablesRule class]; case DOM_WEBKIT_KEYFRAMES_RULE: - wrapperClass = [DOMWebKitCSSKeyframesRule class]; - break; + return [DOMWebKitCSSKeyframesRule class]; case DOM_WEBKIT_KEYFRAME_RULE: - wrapperClass = [DOMWebKitCSSKeyframeRule class]; - break; + return [DOMWebKitCSSKeyframeRule class]; } - return [[[wrapperClass alloc] _initWithCSSRule:impl] autorelease]; + ASSERT_NOT_REACHED(); + return nil; } -@end - - //------------------------------------------------------------------------------------------ // DOMCSSValue -@implementation DOMCSSValue (WebCoreInternal) - -- (WebCore::CSSValue *)_CSSValue -{ - return reinterpret_cast<WebCore::CSSValue*>(_internal); -} - -- (id)_initWithCSSValue:(WebCore::CSSValue *)impl +Class kitClass(WebCore::CSSValue* impl) { - [super _init]; - _internal = reinterpret_cast<DOMObjectInternal*>(impl); - impl->ref(); - WebCore::addDOMWrapper(self, impl); - return self; -} - -+ (DOMCSSValue *)_wrapCSSValue:(WebCore::CSSValue *)impl -{ - if (!impl) - return nil; - - id cachedInstance; - cachedInstance = WebCore::getDOMWrapper(impl); - if (cachedInstance) - return [[cachedInstance retain] autorelease]; - - Class wrapperClass = nil; switch (impl->cssValueType()) { - case DOM_CSS_PRIMITIVE_VALUE: - wrapperClass = [DOMCSSPrimitiveValue class]; - break; - case DOM_CSS_VALUE_LIST: - wrapperClass = [DOMCSSValueList class]; - break; - case DOM_CSS_INHERIT: - wrapperClass = [DOMCSSValue class]; - break; - case DOM_CSS_CUSTOM: -#if ENABLE(SVG) + case WebCore::CSSValue::CSS_PRIMITIVE_VALUE: + return [DOMCSSPrimitiveValue class]; + case WebCore::CSSValue::CSS_VALUE_LIST: + return [DOMCSSValueList class]; + case WebCore::CSSValue::CSS_INHERIT: + case WebCore::CSSValue::CSS_INITIAL: + return [DOMCSSValue class]; + case WebCore::CSSValue::CSS_CUSTOM: +#if ENABLE(SVG_DOM_OBJC_BINDINGS) if (impl->isSVGPaint()) - wrapperClass = [DOMSVGPaint class]; - else if (impl->isSVGColor()) - wrapperClass = [DOMSVGColor class]; - else + return [DOMSVGPaint class]; + if (impl->isSVGColor()) + return [DOMSVGColor class]; #endif - wrapperClass = [DOMCSSValue class]; - break; + return [DOMCSSValue class]; } - return [[[wrapperClass alloc] _initWithCSSValue:impl] autorelease]; + ASSERT_NOT_REACHED(); + return nil; } -@end - - //------------------------------------------------------------------------------------------ // DOMCSSStyleDeclaration CSS2 Properties diff --git a/WebCore/bindings/objc/DOMEvents.mm b/WebCore/bindings/objc/DOMEvents.mm index 6f7f72d..c901e12 100644 --- a/WebCore/bindings/objc/DOMEvents.mm +++ b/WebCore/bindings/objc/DOMEvents.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2006 Jonas Witt <jonas.witt@gmail.com> * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com> * @@ -26,85 +26,46 @@ */ #import "config.h" -#import "DOMEvents.h" +#import "DOMEventInternal.h" -#import "DOMInternal.h" +#import "DOMKeyboardEvent.h" #import "DOMMessageEvent.h" -#import "DOMPrivate.h" +#import "DOMMouseEvent.h" +#import "DOMMutationEvent.h" +#import "DOMOverflowEvent.h" #import "DOMProgressEvent.h" +#import "DOMTextEvent.h" +#import "DOMWheelEvent.h" #import "Event.h" -#import "KeyboardEvent.h" -#import "MessageEvent.h" -#import "MouseEvent.h" -#import "MutationEvent.h" -#import "OverflowEvent.h" -#import "ProgressEvent.h" -#import "UIEvent.h" -#if ENABLE(SVG) +#if ENABLE(SVG_DOM_OBJC_BINDINGS) #import "DOMSVGZoomEvent.h" -#import "SVGZoomEvent.h" #endif -//------------------------------------------------------------------------------------------ -// DOMEvent - -@implementation DOMEvent (WebCoreInternal) - -- (WebCore::Event *)_event -{ - return reinterpret_cast<WebCore::Event*>(_internal); -} - -- (id)_initWithEvent:(WebCore::Event *)impl -{ - ASSERT(impl); - - [super _init]; - _internal = reinterpret_cast<DOMObjectInternal *>(impl); - impl->ref(); - WebCore::addDOMWrapper(self, impl); - return self; -} - -+ (DOMEvent *)_wrapEvent:(WebCore::Event *)impl +Class kitClass(WebCore::Event* impl) { - if (!impl) - return nil; - - id cachedInstance; - cachedInstance = WebCore::getDOMWrapper(impl); - if (cachedInstance) - return [[cachedInstance retain] autorelease]; - - Class wrapperClass = nil; if (impl->isUIEvent()) { if (impl->isKeyboardEvent()) - wrapperClass = [DOMKeyboardEvent class]; - else if (impl->isTextEvent()) - wrapperClass = [DOMTextEvent class]; - else if (impl->isMouseEvent()) - wrapperClass = [DOMMouseEvent class]; - else if (impl->isWheelEvent()) - wrapperClass = [DOMWheelEvent class]; -#if ENABLE(SVG) - else if (impl->isSVGZoomEvent()) - wrapperClass = [DOMSVGZoomEvent class]; + return [DOMKeyboardEvent class]; + if (impl->isTextEvent()) + return [DOMTextEvent class]; + if (impl->isMouseEvent()) + return [DOMMouseEvent class]; + if (impl->isWheelEvent()) + return [DOMWheelEvent class]; +#if ENABLE(SVG_DOM_OBJC_BINDINGS) + if (impl->isSVGZoomEvent()) + return [DOMSVGZoomEvent class]; #endif - else - wrapperClass = [DOMUIEvent class]; - } else if (impl->isMutationEvent()) - wrapperClass = [DOMMutationEvent class]; - else if (impl->isOverflowEvent()) - wrapperClass = [DOMOverflowEvent class]; - else if (impl->isMessageEvent()) - wrapperClass = [DOMMessageEvent class]; - else if (impl->isProgressEvent()) - wrapperClass = [DOMProgressEvent class]; - else - wrapperClass = [DOMEvent class]; - - return [[[wrapperClass alloc] _initWithEvent:impl] autorelease]; + return [DOMUIEvent class]; + } + if (impl->isMutationEvent()) + return [DOMMutationEvent class]; + if (impl->isOverflowEvent()) + return [DOMOverflowEvent class]; + if (impl->isMessageEvent()) + return [DOMMessageEvent class]; + if (impl->isProgressEvent()) + return [DOMProgressEvent class]; + return [DOMEvent class]; } - -@end diff --git a/WebCore/bindings/objc/DOMHTML.h b/WebCore/bindings/objc/DOMHTML.h index cd80612..c336c04 100644 --- a/WebCore/bindings/objc/DOMHTML.h +++ b/WebCore/bindings/objc/DOMHTML.h @@ -26,6 +26,8 @@ #import <WebCore/DOMCore.h> +#import <WebCore/DOMFile.h> +#import <WebCore/DOMFileList.h> #import <WebCore/DOMHTMLAnchorElement.h> #import <WebCore/DOMHTMLAppletElement.h> #import <WebCore/DOMHTMLAreaElement.h> diff --git a/WebCore/bindings/objc/DOMHTML.mm b/WebCore/bindings/objc/DOMHTML.mm index baf5774..8c0d30b 100644 --- a/WebCore/bindings/objc/DOMHTML.mm +++ b/WebCore/bindings/objc/DOMHTML.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com> * * Redistribution and use in source and binary forms, with or without @@ -25,20 +25,27 @@ */ #import "config.h" -#import "DOMHTML.h" -#import "CSSHelper.h" +#import "DOMDocumentFragmentInternal.h" #import "DOMExtensions.h" -#import "DOMInternal.h" +#import "DOMHTMLCollectionInternal.h" +#import "DOMHTMLDocumentInternal.h" +#import "DOMHTMLInputElementInternal.h" +#import "DOMHTMLSelectElementInternal.h" +#import "DOMHTMLTextAreaElementInternal.h" +#import "DOMNodeInternal.h" #import "DOMPrivate.h" #import "DocumentFragment.h" #import "FrameView.h" +#import "HTMLCollection.h" #import "HTMLDocument.h" #import "HTMLInputElement.h" -#import "HTMLObjectElement.h" #import "HTMLSelectElement.h" +#import "HTMLTextAreaElement.h" +#import "Page.h" #import "Range.h" #import "RenderTextControl.h" +#import "Settings.h" #import "markup.h" //------------------------------------------------------------------------------------------ @@ -48,13 +55,13 @@ - (DOMDocumentFragment *)createDocumentFragmentWithMarkupString:(NSString *)markupString baseURL:(NSURL *)baseURL { - return [DOMDocumentFragment _wrapDocumentFragment:createFragmentFromMarkup([self _document], markupString, [baseURL absoluteString]).get()]; + return kit(createFragmentFromMarkup(core(self), markupString, [baseURL absoluteString]).get()); } - (DOMDocumentFragment *)createDocumentFragmentWithText:(NSString *)text { // FIXME: Since this is not a contextual fragment, it won't handle whitespace properly. - return [DOMDocumentFragment _wrapDocumentFragment:createFragmentFromText([self _document]->createRange().get(), text).get()]; + return kit(createFragmentFromText(core(self)->createRange().get(), text).get()); } @end @@ -63,7 +70,7 @@ - (DOMDocumentFragment *)_createDocumentFragmentWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString { - NSURL *baseURL = [self _document]->completeURL(WebCore::parseURL(baseURLString)); + NSURL *baseURL = core(self)->completeURL(WebCore::parseURL(baseURLString)); return [self createDocumentFragmentWithMarkupString:markupString baseURL:baseURL]; } @@ -74,49 +81,40 @@ @end -#pragma mark DOM EXTENSIONS +#ifdef BUILDING_ON_TIGER +@implementation DOMHTMLDocument (DOMHTMLDocumentOverrides) -@implementation DOMHTMLInputElement(FormAutoFillTransition) +- (DOMNode *)firstChild +{ + WebCore::HTMLDocument* coreHTMLDocument = core(self); + if (!coreHTMLDocument->page() || !coreHTMLDocument->page()->settings()->needsTigerMailQuirks()) + return kit(coreHTMLDocument->firstChild()); + + WebCore::Node* child = coreHTMLDocument->firstChild(); + while (child && child->nodeType() == WebCore::Node::DOCUMENT_TYPE_NODE) + child = child->nextSibling(); + + return kit(child); +} + +@end +#endif + +@implementation DOMHTMLInputElement (FormAutoFillTransition) - (BOOL)_isTextField { - // We could make this public API as-is, or we could change it into a method that returns whether - // the element is a text field or a button or ... ? - static NSArray *textInputTypes = nil; -#ifndef NDEBUG - static NSArray *nonTextInputTypes = nil; -#endif - - NSString *fieldType = [self type]; - - // No type at all is treated as text type - if ([fieldType length] == 0) - return YES; - - if (textInputTypes == nil) - textInputTypes = [[NSSet alloc] initWithObjects:@"text", @"password", @"search", @"isindex", nil]; - - BOOL isText = [textInputTypes containsObject:[fieldType lowercaseString]]; - -#ifndef NDEBUG - if (nonTextInputTypes == nil) - nonTextInputTypes = [[NSSet alloc] initWithObjects:@"checkbox", @"radio", @"submit", @"reset", @"file", @"hidden", @"image", @"button", @"range", nil]; - - // Catch cases where a new input type has been added that's not in these lists. - ASSERT(isText || [nonTextInputTypes containsObject:[fieldType lowercaseString]]); -#endif - - return isText; + return core(self)->isTextField(); } - (NSRect)_rectOnScreen { // Returns bounding rect of text field, in screen coordinates. NSRect result = [self boundingBox]; - if (![self _HTMLInputElement]->document()->view()) + if (!core(self)->document()->view()) return result; - NSView* view = [self _HTMLInputElement]->document()->view()->documentView(); + NSView* view = core(self)->document()->view()->documentView(); result = [view convertRect:result toView:nil]; result.origin = [[view window] convertBaseToScreen:result.origin]; return result; @@ -124,7 +122,7 @@ - (void)_replaceCharactersInRange:(NSRange)targetRange withString:(NSString *)replacementString selectingFromIndex:(int)index { - WebCore::HTMLInputElement* inputElement = [self _HTMLInputElement]; + WebCore::HTMLInputElement* inputElement = core(self); if (inputElement) { WebCore::String newValue = inputElement->value(); newValue.replace(targetRange.location, targetRange.length, replacementString); @@ -135,7 +133,7 @@ - (NSRange)_selectedRange { - WebCore::HTMLInputElement* inputElement = [self _HTMLInputElement]; + WebCore::HTMLInputElement* inputElement = core(self); if (inputElement) { int start = inputElement->selectionStart(); int end = inputElement->selectionEnd(); @@ -149,9 +147,7 @@ // This notifies the input element that the content has been autofilled // This allows WebKit to obey the -webkit-autofill pseudo style, which // changes the background color. - WebCore::HTMLInputElement* inputElement = [self _HTMLInputElement]; - if (inputElement) - inputElement->setAutofilled(filled); + core(self)->setAutofilled(filled); } @end @@ -160,30 +156,35 @@ - (void)_activateItemAtIndex:(int)index { - if (WebCore::HTMLSelectElement* select = [self _HTMLSelectElement]) + if (WebCore::HTMLSelectElement* select = core(self)) select->setSelectedIndex(index); } @end @implementation DOMHTMLInputElement (FormPromptAdditions) + - (BOOL)_isEdited { - WebCore::RenderObject *renderer = [self _node]->renderer(); - if (renderer && [self _isTextField]) - return static_cast<WebCore::RenderTextControl *>(renderer)->isUserEdited(); - - return NO; + WebCore::RenderObject *renderer = core(self)->renderer(); + return renderer && [self _isTextField] && static_cast<WebCore::RenderTextControl *>(renderer)->isUserEdited(); } + @end @implementation DOMHTMLTextAreaElement (FormPromptAdditions) + - (BOOL)_isEdited { - WebCore::RenderObject *renderer = [self _node]->renderer(); - if (renderer) - return static_cast<WebCore::RenderTextControl *>(renderer)->isUserEdited(); - - return NO; + WebCore::RenderObject* renderer = core(self)->renderer(); + return renderer && static_cast<WebCore::RenderTextControl*>(renderer)->isUserEdited(); } + @end + +Class kitClass(WebCore::HTMLCollection* collection) +{ + if (collection->type() == WebCore::SelectOptions) + return [DOMHTMLOptionsCollection class]; + return [DOMHTMLCollection class]; +} diff --git a/WebCore/bindings/objc/DOMInternal.h b/WebCore/bindings/objc/DOMInternal.h index 9ddcada..48f5d2f 100644 --- a/WebCore/bindings/objc/DOMInternal.h +++ b/WebCore/bindings/objc/DOMInternal.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2006 James G. Speth (speth@end.com) * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) * @@ -25,272 +25,18 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "DOM.h" - +// This is lets our internals access DOMObject's _internal field while having +// it be private for clients outside WebKit. +#define private public #import "DOMObject.h" -#import "HitTestResult.h" +#undef private -#if ENABLE(XPATH) -#import "DOMXPathExpressionInternal.h" +#import "DOMNodeFilter.h" #import "DOMXPathNSResolver.h" -#import "DOMXPathResultInternal.h" -#endif // ENABLE(XPATH) - -// Auto-generated internal interfaces -#import "DOMAbstractViewInternal.h" -#import "DOMAttrInternal.h" -#import "DOMCDATASectionInternal.h" -#import "DOMCSSCharsetRuleInternal.h" -#import "DOMCSSFontFaceRuleInternal.h" -#import "DOMCSSImportRuleInternal.h" -#import "DOMCSSMediaRuleInternal.h" -#import "DOMCSSPageRuleInternal.h" -#import "DOMCSSPrimitiveValueInternal.h" -#import "DOMCSSRuleInternal.h" -#import "DOMCSSRuleListInternal.h" -#import "DOMCSSStyleDeclarationInternal.h" -#import "DOMCSSStyleRuleInternal.h" -#import "DOMCSSStyleSheetInternal.h" -#import "DOMCSSUnknownRuleInternal.h" -#import "DOMCSSValueInternal.h" -#import "DOMCSSValueListInternal.h" -#import "DOMCSSVariablesRuleInternal.h" -#import "DOMCSSVariablesDeclarationInternal.h" -#import "DOMCharacterDataInternal.h" -#import "DOMCommentInternal.h" -#import "DOMCounterInternal.h" -#import "DOMDOMImplementationInternal.h" -#import "DOMDocumentFragmentInternal.h" -#import "DOMDocumentInternal.h" -#import "DOMDocumentTypeInternal.h" -#import "DOMElementInternal.h" -#import "DOMEntityInternal.h" -#import "DOMEntityReferenceInternal.h" -#import "DOMEventInternal.h" -#import "DOMFileInternal.h" -#import "DOMFileListInternal.h" -#import "DOMHTMLAnchorElementInternal.h" -#import "DOMHTMLAppletElementInternal.h" -#import "DOMHTMLAreaElementInternal.h" -#import "DOMHTMLBRElementInternal.h" -#import "DOMHTMLBaseElementInternal.h" -#import "DOMHTMLBaseFontElementInternal.h" -#import "DOMHTMLBodyElementInternal.h" -#import "DOMHTMLButtonElementInternal.h" -#import "DOMHTMLCollectionInternal.h" -#import "DOMHTMLDListElementInternal.h" -#import "DOMHTMLDirectoryElementInternal.h" -#import "DOMHTMLDivElementInternal.h" -#import "DOMHTMLDocumentInternal.h" -#import "DOMHTMLElementInternal.h" -#import "DOMHTMLEmbedElementInternal.h" -#import "DOMHTMLFieldSetElementInternal.h" -#import "DOMHTMLFontElementInternal.h" -#import "DOMHTMLFormElementInternal.h" -#import "DOMHTMLFrameElementInternal.h" -#import "DOMHTMLFrameSetElementInternal.h" -#import "DOMHTMLHRElementInternal.h" -#import "DOMHTMLHeadElementInternal.h" -#import "DOMHTMLHeadingElementInternal.h" -#import "DOMHTMLHtmlElementInternal.h" -#import "DOMHTMLIFrameElementInternal.h" -#import "DOMHTMLImageElementInternal.h" -#import "DOMHTMLInputElementInternal.h" -#import "DOMHTMLIsIndexElementInternal.h" -#import "DOMHTMLLIElementInternal.h" -#import "DOMHTMLLabelElementInternal.h" -#import "DOMHTMLLegendElementInternal.h" -#import "DOMHTMLLinkElementInternal.h" -#import "DOMHTMLMapElementInternal.h" -#import "DOMHTMLMarqueeElementInternal.h" -#import "DOMHTMLMenuElementInternal.h" -#import "DOMHTMLMetaElementInternal.h" -#import "DOMHTMLModElementInternal.h" -#import "DOMHTMLOListElementInternal.h" -#import "DOMHTMLObjectElementInternal.h" -#import "DOMHTMLOptGroupElementInternal.h" -#import "DOMHTMLOptionElementInternal.h" -#import "DOMHTMLOptionsCollectionInternal.h" -#import "DOMHTMLParagraphElementInternal.h" -#import "DOMHTMLParamElementInternal.h" -#import "DOMHTMLPreElementInternal.h" -#import "DOMHTMLQuoteElementInternal.h" -#import "DOMHTMLScriptElementInternal.h" -#import "DOMHTMLSelectElementInternal.h" -#import "DOMHTMLStyleElementInternal.h" -#import "DOMHTMLTableCaptionElementInternal.h" -#import "DOMHTMLTableCellElementInternal.h" -#import "DOMHTMLTableColElementInternal.h" -#import "DOMHTMLTableElementInternal.h" -#import "DOMHTMLTableRowElementInternal.h" -#import "DOMHTMLTableSectionElementInternal.h" -#import "DOMHTMLTextAreaElementInternal.h" -#import "DOMHTMLTitleElementInternal.h" -#import "DOMHTMLUListElementInternal.h" -#import "DOMKeyboardEventInternal.h" -#import "DOMMediaListInternal.h" -#import "DOMMessagePortInternal.h" -#import "DOMMouseEventInternal.h" -#import "DOMMutationEventInternal.h" -#import "DOMNamedNodeMapInternal.h" -#import "DOMNodeInternal.h" -#import "DOMNodeIteratorInternal.h" -#import "DOMNodeListInternal.h" -#import "DOMNotationInternal.h" -#import "DOMOverflowEventInternal.h" -#import "DOMProcessingInstructionInternal.h" -#import "DOMRGBColorInternal.h" -#import "DOMRangeInternal.h" -#import "DOMRectInternal.h" -#import "DOMStyleSheetInternal.h" -#import "DOMStyleSheetListInternal.h" -#import "DOMTextEventInternal.h" -#import "DOMTextInternal.h" -#import "DOMTreeWalkerInternal.h" -#import "DOMUIEventInternal.h" -#import "DOMWebKitCSSKeyframeRuleInternal.h" -#import "DOMWebKitCSSKeyframesRuleInternal.h" -#import "DOMWebKitCSSMatrixInternal.h" -#import "DOMWebKitCSSTransformValueInternal.h" -#import "DOMWheelEventInternal.h" - -#if ENABLE(SVG) -#import "DOMSVGAElementInternal.h" -#import "DOMSVGAltGlyphElementInternal.h" -#import "DOMSVGAngleInternal.h" -#import "DOMSVGAnimateColorElementInternal.h" -#import "DOMSVGAnimateElementInternal.h" -#import "DOMSVGAnimateTransformElementInternal.h" -#import "DOMSVGAnimatedAngleInternal.h" -#import "DOMSVGAnimatedBooleanInternal.h" -#import "DOMSVGAnimatedEnumerationInternal.h" -#import "DOMSVGAnimatedIntegerInternal.h" -#import "DOMSVGAnimatedLengthInternal.h" -#import "DOMSVGAnimatedLengthListInternal.h" -#import "DOMSVGAnimatedNumberInternal.h" -#import "DOMSVGAnimatedNumberListInternal.h" -#import "DOMSVGAnimatedPreserveAspectRatioInternal.h" -#import "DOMSVGAnimatedRectInternal.h" -#import "DOMSVGAnimatedStringInternal.h" -#import "DOMSVGAnimatedTransformListInternal.h" -#import "DOMSVGAnimationElementInternal.h" -#import "DOMSVGCircleElementInternal.h" -#import "DOMSVGClipPathElementInternal.h" -#import "DOMSVGColorInternal.h" -#import "DOMSVGComponentTransferFunctionElementInternal.h" -#import "DOMSVGCursorElementInternal.h" -#import "DOMSVGDefsElementInternal.h" -#import "DOMSVGDefinitionSrcElementInternal.h" -#import "DOMSVGDescElementInternal.h" -#import "DOMSVGDocumentInternal.h" -#import "DOMSVGElementInternal.h" -#import "DOMSVGElementInstanceInternal.h" -#import "DOMSVGElementInstanceListInternal.h" -#import "DOMSVGEllipseElementInternal.h" -#import "DOMSVGFEBlendElementInternal.h" -#import "DOMSVGFEColorMatrixElementInternal.h" -#import "DOMSVGFEComponentTransferElementInternal.h" -#import "DOMSVGFECompositeElementInternal.h" -#import "DOMSVGFEDiffuseLightingElementInternal.h" -#import "DOMSVGFEDisplacementMapElementInternal.h" -#import "DOMSVGFEDistantLightElementInternal.h" -#import "DOMSVGFEFloodElementInternal.h" -#import "DOMSVGFEFuncAElementInternal.h" -#import "DOMSVGFEFuncBElementInternal.h" -#import "DOMSVGFEFuncGElementInternal.h" -#import "DOMSVGFEFuncRElementInternal.h" -#import "DOMSVGFEGaussianBlurElementInternal.h" -#import "DOMSVGFEImageElementInternal.h" -#import "DOMSVGFEMergeElementInternal.h" -#import "DOMSVGFEMergeNodeElementInternal.h" -#import "DOMSVGFEOffsetElementInternal.h" -#import "DOMSVGFEPointLightElementInternal.h" -#import "DOMSVGFESpecularLightingElementInternal.h" -#import "DOMSVGFESpotLightElementInternal.h" -#import "DOMSVGFETileElementInternal.h" -#import "DOMSVGFETurbulenceElementInternal.h" -#import "DOMSVGFilterElementInternal.h" -#import "DOMSVGFontElementInternal.h" -#import "DOMSVGFontFaceElementInternal.h" -#import "DOMSVGFontFaceFormatElementInternal.h" -#import "DOMSVGFontFaceNameElementInternal.h" -#import "DOMSVGFontFaceSrcElementInternal.h" -#import "DOMSVGFontFaceUriElementInternal.h" -#import "DOMSVGForeignObjectElementInternal.h" -#import "DOMSVGGElementInternal.h" -#import "DOMSVGGlyphElementInternal.h" -#import "DOMSVGGradientElementInternal.h" -#import "DOMSVGImageElementInternal.h" -#import "DOMSVGLengthInternal.h" -#import "DOMSVGLengthListInternal.h" -#import "DOMSVGLineElementInternal.h" -#import "DOMSVGLinearGradientElementInternal.h" -#import "DOMSVGMarkerElementInternal.h" -#import "DOMSVGMaskElementInternal.h" -#import "DOMSVGMatrixInternal.h" -#import "DOMSVGMetadataElementInternal.h" -#import "DOMSVGMissingGlyphElementInternal.h" -#import "DOMSVGNumberInternal.h" -#import "DOMSVGNumberListInternal.h" -#import "DOMSVGPaintInternal.h" -#import "DOMSVGPathElementInternal.h" -#import "DOMSVGPathSegArcAbsInternal.h" -#import "DOMSVGPathSegArcRelInternal.h" -#import "DOMSVGPathSegClosePathInternal.h" -#import "DOMSVGPathSegCurvetoCubicAbsInternal.h" -#import "DOMSVGPathSegCurvetoCubicRelInternal.h" -#import "DOMSVGPathSegCurvetoCubicSmoothAbsInternal.h" -#import "DOMSVGPathSegCurvetoCubicSmoothRelInternal.h" -#import "DOMSVGPathSegCurvetoQuadraticAbsInternal.h" -#import "DOMSVGPathSegCurvetoQuadraticRelInternal.h" -#import "DOMSVGPathSegCurvetoQuadraticSmoothAbsInternal.h" -#import "DOMSVGPathSegCurvetoQuadraticSmoothRelInternal.h" -#import "DOMSVGPathSegInternal.h" -#import "DOMSVGPathSegLinetoAbsInternal.h" -#import "DOMSVGPathSegLinetoHorizontalAbsInternal.h" -#import "DOMSVGPathSegLinetoHorizontalRelInternal.h" -#import "DOMSVGPathSegLinetoRelInternal.h" -#import "DOMSVGPathSegLinetoVerticalAbsInternal.h" -#import "DOMSVGPathSegLinetoVerticalRelInternal.h" -#import "DOMSVGPathSegListInternal.h" -#import "DOMSVGPathSegMovetoAbsInternal.h" -#import "DOMSVGPathSegMovetoRelInternal.h" -#import "DOMSVGPatternElementInternal.h" -#import "DOMSVGPointInternal.h" -#import "DOMSVGPointListInternal.h" -#import "DOMSVGPolygonElementInternal.h" -#import "DOMSVGPolylineElementInternal.h" -#import "DOMSVGPreserveAspectRatioInternal.h" -#import "DOMSVGRadialGradientElementInternal.h" -#import "DOMSVGRectElementInternal.h" -#import "DOMSVGRectInternal.h" -#import "DOMSVGRenderingIntentInternal.h" -#import "DOMSVGSVGElementInternal.h" -#import "DOMSVGScriptElementInternal.h" -#import "DOMSVGSetElementInternal.h" -#import "DOMSVGStopElementInternal.h" -#import "DOMSVGStringListInternal.h" -#import "DOMSVGStyleElementInternal.h" -#import "DOMSVGSwitchElementInternal.h" -#import "DOMSVGSymbolElementInternal.h" -#import "DOMSVGTRefElementInternal.h" -#import "DOMSVGTSpanElementInternal.h" -#import "DOMSVGTextContentElementInternal.h" -#import "DOMSVGTextElementInternal.h" -#import "DOMSVGTextPathElementInternal.h" -#import "DOMSVGTextPositioningElementInternal.h" -#import "DOMSVGTitleElementInternal.h" -#import "DOMSVGTransformInternal.h" -#import "DOMSVGTransformListInternal.h" -#import "DOMSVGUnitTypesInternal.h" -#import "DOMSVGUseElementInternal.h" -#import "DOMSVGViewElementInternal.h" -#import "DOMSVGZoomEventInternal.h" -#endif // ENABLE(SVG) +#import <wtf/Forward.h> namespace JSC { class JSObject; - namespace Bindings { class RootObject; } @@ -298,65 +44,47 @@ namespace JSC { namespace WebCore { class NodeFilter; - -#if ENABLE(SVG) - class TransformationMatrix; - class FloatPoint; - class FloatRect; -#endif // ENABLE(SVG) - #if ENABLE(XPATH) class XPathNSResolver; -#endif // ENABLE(XPATH) +#endif } -// Core Internal Interfaces - -@interface DOMObject (WebCoreInternal) -- (id)_init; -@end - -// Traversal Internal Interfaces - @interface DOMNodeFilter : DOMObject <DOMNodeFilter> -+ (DOMNodeFilter *)_wrapNodeFilter:(WebCore::NodeFilter *)impl; @end #if ENABLE(XPATH) - -// XPath Internal Interfaces - @interface DOMNativeXPathNSResolver : DOMObject <DOMXPathNSResolver> -+ (DOMNativeXPathNSResolver *)_wrapXPathNSResolver:(WebCore::XPathNSResolver *)impl; -- (WebCore::XPathNSResolver *)_xpathNSResolver; @end - #endif // ENABLE(XPATH) // Helper functions for DOM wrappers and gluing to Objective-C -namespace WebCore { +// Create an NSMapTable mapping from pointers to ObjC objects held with zeroing weak references. +NSMapTable* createWrapperCache(); +NSMapTable* createWrapperCacheWithIntegerKeys(); // Same, but from integers to ObjC objects. - // Create an NSMapTable mapping from pointers to ObjC objects held with zeroing weak references. - NSMapTable* createWrapperCache(); - NSMapTable* createWrapperCacheWithIntegerKeys(); // Same, but from integers to ObjC objects. +id createDOMWrapper(JSC::JSObject*, PassRefPtr<JSC::Bindings::RootObject> origin, PassRefPtr<JSC::Bindings::RootObject> current); - id createDOMWrapper(JSC::JSObject*, PassRefPtr<JSC::Bindings::RootObject> origin, PassRefPtr<JSC::Bindings::RootObject> current); +NSObject* getDOMWrapper(DOMObjectInternal*); +void addDOMWrapper(NSObject* wrapper, DOMObjectInternal*); +void removeDOMWrapper(DOMObjectInternal*); - NSObject* getDOMWrapper(DOMObjectInternal*); - void addDOMWrapper(NSObject* wrapper, DOMObjectInternal*); - void removeDOMWrapper(DOMObjectInternal*); +template <class Source> +inline id getDOMWrapper(Source impl) +{ + return getDOMWrapper(reinterpret_cast<DOMObjectInternal*>(impl)); +} - template <class Source> - inline id getDOMWrapper(Source impl) - { - return getDOMWrapper(reinterpret_cast<DOMObjectInternal*>(impl)); - } +template <class Source> +inline void addDOMWrapper(NSObject* wrapper, Source impl) +{ + addDOMWrapper(wrapper, reinterpret_cast<DOMObjectInternal*>(impl)); +} - template <class Source> - inline void addDOMWrapper(NSObject* wrapper, Source impl) - { - addDOMWrapper(wrapper, reinterpret_cast<DOMObjectInternal*>(impl)); - } +DOMNodeFilter *kit(WebCore::NodeFilter*); +WebCore::NodeFilter* core(DOMNodeFilter *); -} // namespace WebCore +#if ENABLE(XPATH) +DOMNativeXPathNSResolver *kit(WebCore::XPathNSResolver*); +WebCore::XPathNSResolver* core(DOMNativeXPathNSResolver *); +#endif // ENABLE(XPATH) diff --git a/WebCore/bindings/objc/DOMInternal.mm b/WebCore/bindings/objc/DOMInternal.mm index ea26d5e..eb98a8a 100644 --- a/WebCore/bindings/objc/DOMInternal.mm +++ b/WebCore/bindings/objc/DOMInternal.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,25 +26,15 @@ #import "config.h" #import "DOMInternal.h" -#import "Document.h" -#import "Event.h" +#import "DOMNodeInternal.h" #import "Frame.h" #import "JSNode.h" -#import "Node.h" -#import "PlatformString.h" -#import "Range.h" -#import "RangeException.h" -#import "SVGException.h" #import "WebScriptObjectPrivate.h" -#import "XPathEvaluator.h" -#import "ScriptController.h" #import "runtime_root.h" //------------------------------------------------------------------------------------------ // Wrapping WebCore implementation objects -namespace WebCore { - static NSMapTable* DOMWrapperCache; NSMapTable* createWrapperCache() @@ -92,8 +82,6 @@ void removeDOMWrapper(DOMObjectInternal* impl) NSMapRemove(DOMWrapperCache, impl); } -} // namespace WebCore - //------------------------------------------------------------------------------------------ @implementation WebScriptObject (WebScriptObjectInternal) @@ -127,7 +115,7 @@ void removeDOMWrapper(DOMObjectInternal* impl) // Extract the WebCore::Node from the ObjectiveC wrapper. DOMNode *n = (DOMNode *)self; - WebCore::Node *nodeImpl = [n _node]; + WebCore::Node *nodeImpl = core(n); // Dig up Interpreter and ExecState. WebCore::Frame *frame = 0; diff --git a/WebCore/bindings/objc/DOMObject.h b/WebCore/bindings/objc/DOMObject.h index 166637d..c4a3f6f 100644 --- a/WebCore/bindings/objc/DOMObject.h +++ b/WebCore/bindings/objc/DOMObject.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2004, 2006, 2009 Apple Inc. All rights reserved. * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com> * * Redistribution and use in source and binary forms, with or without @@ -37,6 +37,7 @@ typedef struct DOMObjectInternal DOMObjectInternal; @interface DOMObject : WebScriptObject <NSCopying> { +@private DOMObjectInternal *_internal; } @end diff --git a/WebCore/bindings/objc/DOMObject.mm b/WebCore/bindings/objc/DOMObject.mm index 8510ae9..d88e86b 100644 --- a/WebCore/bindings/objc/DOMObject.mm +++ b/WebCore/bindings/objc/DOMObject.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006, 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2006, 2006, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2006 James G. Speth <speth@end.com> * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com> * @@ -28,11 +28,11 @@ #import "config.h" #import "DOMObject.h" -#import "DOMHTMLLinkElement.h" -#import "DOMHTMLStyleElement.h" +#import "DOMHTMLLinkElementInternal.h" +#import "DOMHTMLStyleElementInternal.h" #import "DOMInternal.h" -#import "DOMProcessingInstruction.h" -#import "DOMStyleSheet.h" +#import "DOMProcessingInstructionInternal.h" +#import "DOMStyleSheetInternal.h" #import "HTMLLinkElement.h" #import "HTMLStyleElement.h" #import "ProcessingInstruction.h" @@ -53,7 +53,7 @@ - (void)dealloc { if (_internal) - WebCore::removeDOMWrapper(_internal); + removeDOMWrapper(_internal); [super dealloc]; } @@ -69,27 +69,18 @@ - (DOMStyleSheet *)sheet { - WebCore::StyleSheet *styleSheet; + WebCore::StyleSheet* styleSheet; if ([self isKindOfClass:[DOMProcessingInstruction class]]) - styleSheet = static_cast<WebCore::ProcessingInstruction*>([(DOMProcessingInstruction *)self _node])->sheet(); + styleSheet = core(static_cast<DOMProcessingInstruction *>(self))->sheet(); else if ([self isKindOfClass:[DOMHTMLLinkElement class]]) - styleSheet = static_cast<WebCore::HTMLLinkElement*>([(DOMHTMLLinkElement *)self _node])->sheet(); + styleSheet = core(static_cast<DOMHTMLLinkElement *>(self))->sheet(); else if ([self isKindOfClass:[DOMHTMLStyleElement class]]) - styleSheet = static_cast<WebCore::HTMLStyleElement*>([(DOMHTMLStyleElement *)self _node])->sheet(); + styleSheet = core(static_cast<DOMHTMLStyleElement *>(self))->sheet(); else return nil; - return [DOMStyleSheet _wrapStyleSheet:styleSheet]; -} - -@end - -@implementation DOMObject (WebCoreInternal) - -- (id)_init -{ - return [super _init]; + return kit(styleSheet); } @end diff --git a/WebCore/bindings/objc/DOMPrivate.h b/WebCore/bindings/objc/DOMPrivate.h index ba95ce3..4291cbc 100644 --- a/WebCore/bindings/objc/DOMPrivate.h +++ b/WebCore/bindings/objc/DOMPrivate.h @@ -24,45 +24,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import <WebCore/DOMCSS.h> -#import <WebCore/DOMCSSStyleDeclaration.h> -#import <WebCore/DOMElement.h> -#import <WebCore/DOMEvents.h> -#import <WebCore/DOMHTML.h> -#import <WebCore/DOMHTMLDocument.h> -#import <WebCore/DOMHTMLInputElement.h> -#import <WebCore/DOMHTMLSelectElement.h> -#import <WebCore/DOMNode.h> -#import <WebCore/DOMRGBColor.h> -#import <WebCore/DOMRange.h> - -#import <WebCore/DOMDocumentPrivate.h> -#import <WebCore/DOMElementPrivate.h> -#import <WebCore/DOMHTMLAnchorElementPrivate.h> -#import <WebCore/DOMHTMLAreaElementPrivate.h> -#import <WebCore/DOMHTMLBodyElementPrivate.h> -#import <WebCore/DOMHTMLButtonElementPrivate.h> -#import <WebCore/DOMHTMLDocumentPrivate.h> -#import <WebCore/DOMHTMLFormElementPrivate.h> -#import <WebCore/DOMHTMLFrameElementPrivate.h> -#import <WebCore/DOMHTMLImageElementPrivate.h> -#import <WebCore/DOMHTMLInputElementPrivate.h> -#import <WebCore/DOMHTMLLinkElementPrivate.h> -#import <WebCore/DOMHTMLOptionsCollectionPrivate.h> -#import <WebCore/DOMHTMLPreElementPrivate.h> -#import <WebCore/DOMHTMLStyleElementPrivate.h> -#import <WebCore/DOMHTMLTextAreaElementPrivate.h> -#import <WebCore/DOMKeyboardEventPrivate.h> -#import <WebCore/DOMMouseEventPrivate.h> -#import <WebCore/DOMNodeIteratorPrivate.h> -#import <WebCore/DOMNodePrivate.h> -#import <WebCore/DOMProcessingInstructionPrivate.h> -#import <WebCore/DOMRangePrivate.h> -#import <WebCore/DOMUIEventPrivate.h> -#import <WebCore/DOMWheelEventPrivate.h> +#import <WebCore/DOM.h> @interface DOMNode (DOMNodeExtensionsPendingPublic) - (NSImage *)renderedImage; +- (NSArray *)textRects; @end // FIXME: this should be removed as soon as all internal Apple uses of it have been replaced with @@ -79,7 +45,8 @@ @interface DOMRange (DOMRangeExtensions) - (NSRect)boundingBox; -- (NSArray *)lineBoxRects; +- (NSArray *)lineBoxRects; // Deprecated. Use textRects instead. +- (NSArray *)textRects; @end @interface DOMElement (WebPrivate) diff --git a/WebCore/bindings/objc/DOMRGBColor.mm b/WebCore/bindings/objc/DOMRGBColor.mm index 5921b8e..27f8966 100644 --- a/WebCore/bindings/objc/DOMRGBColor.mm +++ b/WebCore/bindings/objc/DOMRGBColor.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) * * Redistribution and use in source and binary forms, with or without @@ -25,18 +25,15 @@ */ #import "config.h" -#import "DOMRGBColor.h" +#import "DOMInternal.h" // import first to make the private/public trick work +#import "DOMRGBColorInternal.h" #import "CSSPrimitiveValue.h" -#import "Color.h" #import "ColorMac.h" -#import "DOMCSSPrimitiveValue.h" -#import "DOMInternal.h" +#import "DOMCSSPrimitiveValueInternal.h" #import "WebCoreObjCExtras.h" +#import "WebScriptObjectPrivate.h" #import <runtime/InitializeThreading.h> -#import <wtf/GetPtr.h> - -namespace WebCore { static NSMapTable* RGBColorWrapperCache; @@ -63,9 +60,6 @@ static void removeWrapperForRGB(WebCore::RGBA32 value) NSMapRemove(RGBColorWrapperCache, reinterpret_cast<const void*>(value)); } -} // namespace WebCore - - @implementation DOMRGBColor + (void)initialize @@ -81,7 +75,7 @@ static void removeWrapperForRGB(WebCore::RGBA32 value) if (WebCoreObjCScheduleDeallocateOnMainThread([DOMRGBColor class], self)) return; - WebCore::removeWrapperForRGB(reinterpret_cast<uintptr_t>(_internal)); + removeWrapperForRGB(reinterpret_cast<uintptr_t>(_internal)); _internal = 0; [super dealloc]; } @@ -90,28 +84,28 @@ static void removeWrapperForRGB(WebCore::RGBA32 value) { WebCore::RGBA32 rgb = reinterpret_cast<uintptr_t>(_internal); int value = (rgb >> 16) & 0xFF; - return [DOMCSSPrimitiveValue _wrapCSSPrimitiveValue:WebCore::CSSPrimitiveValue::create(value, WebCore::CSSPrimitiveValue::CSS_NUMBER).get()]; + return kit(WebCore::CSSPrimitiveValue::create(value, WebCore::CSSPrimitiveValue::CSS_NUMBER).get()); } - (DOMCSSPrimitiveValue *)green { WebCore::RGBA32 rgb = reinterpret_cast<uintptr_t>(_internal); int value = (rgb >> 8) & 0xFF; - return [DOMCSSPrimitiveValue _wrapCSSPrimitiveValue:WebCore::CSSPrimitiveValue::create(value, WebCore::CSSPrimitiveValue::CSS_NUMBER).get()]; + return kit(WebCore::CSSPrimitiveValue::create(value, WebCore::CSSPrimitiveValue::CSS_NUMBER).get()); } - (DOMCSSPrimitiveValue *)blue { WebCore::RGBA32 rgb = reinterpret_cast<uintptr_t>(_internal); int value = rgb & 0xFF; - return [DOMCSSPrimitiveValue _wrapCSSPrimitiveValue:WebCore::CSSPrimitiveValue::create(value, WebCore::CSSPrimitiveValue::CSS_NUMBER).get()]; + return kit(WebCore::CSSPrimitiveValue::create(value, WebCore::CSSPrimitiveValue::CSS_NUMBER).get()); } - (DOMCSSPrimitiveValue *)alpha { WebCore::RGBA32 rgb = reinterpret_cast<uintptr_t>(_internal); float value = static_cast<float>(WebCore::Color(rgb).alpha()) / 0xFF; - return [DOMCSSPrimitiveValue _wrapCSSPrimitiveValue:WebCore::CSSPrimitiveValue::create(value, WebCore::CSSPrimitiveValue::CSS_NUMBER).get()]; + return kit(WebCore::CSSPrimitiveValue::create(value, WebCore::CSSPrimitiveValue::CSS_NUMBER).get()); } @@ -134,28 +128,18 @@ static void removeWrapperForRGB(WebCore::RGBA32 value) @end -@implementation DOMRGBColor (WebCoreInternal) - -- (WebCore::RGBA32)_RGBColor +WebCore::RGBA32 core(DOMRGBColor *color) { - return static_cast<WebCore::RGBA32>(reinterpret_cast<uintptr_t>(_internal)); + return color ? static_cast<WebCore::RGBA32>(reinterpret_cast<uintptr_t>(color->_internal)) : 0; } -- (id)_initWithRGB:(WebCore::RGBA32)value +DOMRGBColor *kit(WebCore::RGBA32 value) { - [super _init]; - _internal = reinterpret_cast<DOMObjectInternal*>(value); - WebCore::setWrapperForRGB(self, value); - return self; -} + if (DOMRGBColor *wrapper = getWrapperForRGB(value)) + return [[wrapper retain] autorelease]; -+ (DOMRGBColor *)_wrapRGBColor:(WebCore::RGBA32)value -{ - id cachedInstance; - cachedInstance = WebCore::getWrapperForRGB(value); - if (cachedInstance) - return [[cachedInstance retain] autorelease]; - return [[[self alloc] _initWithRGB:value] autorelease]; + DOMRGBColor *wrapper = [[DOMRGBColor alloc] _init]; + wrapper->_internal = reinterpret_cast<DOMObjectInternal*>(value); + setWrapperForRGB(wrapper, value); + return [wrapper autorelease]; } - -@end diff --git a/WebCore/bindings/objc/DOMSVGPathSegInternal.mm b/WebCore/bindings/objc/DOMSVGPathSegInternal.mm index cbbe6bd..1710f88 100644 --- a/WebCore/bindings/objc/DOMSVGPathSegInternal.mm +++ b/WebCore/bindings/objc/DOMSVGPathSegInternal.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2006, 2009 Apple Inc. All rights reserved. * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com> * * Redistribution and use in source and binary forms, with or without @@ -30,8 +30,6 @@ #import "DOMSVGPathSegInternal.h" -#import "DOMInternal.h" -#import "DOMSVGPathSeg.h" #import "DOMSVGPathSegArcAbs.h" #import "DOMSVGPathSegArcRel.h" #import "DOMSVGPathSegClosePath.h" @@ -53,102 +51,53 @@ #import "DOMSVGPathSegMovetoAbs.h" #import "DOMSVGPathSegMovetoRel.h" #import "SVGPathSeg.h" -#import <objc/objc-class.h> -@implementation DOMSVGPathSeg (WebCoreInternal) - -- (WebCore::SVGPathSeg *)_SVGPathSeg -{ - return reinterpret_cast<WebCore::SVGPathSeg*>(_internal); -} - -- (id)_initWithSVGPathSeg:(WebCore::SVGPathSeg *)impl +Class kitClass(WebCore::SVGPathSeg* impl) { - ASSERT(impl); - - [super _init]; - _internal = reinterpret_cast<DOMObjectInternal*>(impl); - impl->ref(); - WebCore::addDOMWrapper(self, impl); - return self; -} - -+ (DOMSVGPathSeg *)_wrapSVGPathSeg:(WebCore::SVGPathSeg *)impl -{ - if (!impl) - return nil; - id cachedInstance; - cachedInstance = WebCore::getDOMWrapper(impl); - if (cachedInstance) - return [[cachedInstance retain] autorelease]; - - Class wrapperClass = nil; switch (impl->pathSegType()) { case WebCore::SVGPathSeg::PATHSEG_UNKNOWN: - wrapperClass = [DOMSVGPathSeg class]; - break; + return [DOMSVGPathSeg class]; case WebCore::SVGPathSeg::PATHSEG_CLOSEPATH: - wrapperClass = [DOMSVGPathSegClosePath class]; - break; + return [DOMSVGPathSegClosePath class]; case WebCore::SVGPathSeg::PATHSEG_MOVETO_ABS: - wrapperClass = [DOMSVGPathSegMovetoAbs class]; - break; + return [DOMSVGPathSegMovetoAbs class]; case WebCore::SVGPathSeg::PATHSEG_MOVETO_REL: - wrapperClass = [DOMSVGPathSegMovetoRel class]; - break; + return [DOMSVGPathSegMovetoRel class]; case WebCore::SVGPathSeg::PATHSEG_LINETO_ABS: - wrapperClass = [DOMSVGPathSegLinetoAbs class]; - break; + return [DOMSVGPathSegLinetoAbs class]; case WebCore::SVGPathSeg::PATHSEG_LINETO_REL: - wrapperClass = [DOMSVGPathSegLinetoRel class]; - break; + return [DOMSVGPathSegLinetoRel class]; case WebCore::SVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS: - wrapperClass = [DOMSVGPathSegCurvetoCubicAbs class]; - break; + return [DOMSVGPathSegCurvetoCubicAbs class]; case WebCore::SVGPathSeg::PATHSEG_CURVETO_CUBIC_REL: - wrapperClass = [DOMSVGPathSegCurvetoCubicRel class]; - break; + return [DOMSVGPathSegCurvetoCubicRel class]; case WebCore::SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_ABS: - wrapperClass = [DOMSVGPathSegCurvetoQuadraticAbs class]; - break; + return [DOMSVGPathSegCurvetoQuadraticAbs class]; case WebCore::SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_REL: - wrapperClass = [DOMSVGPathSegCurvetoQuadraticRel class]; - break; + return [DOMSVGPathSegCurvetoQuadraticRel class]; case WebCore::SVGPathSeg::PATHSEG_ARC_ABS: - wrapperClass = [DOMSVGPathSegArcAbs class]; - break; + return [DOMSVGPathSegArcAbs class]; case WebCore::SVGPathSeg::PATHSEG_ARC_REL: - wrapperClass = [DOMSVGPathSegArcRel class]; - break; + return [DOMSVGPathSegArcRel class]; case WebCore::SVGPathSeg::PATHSEG_LINETO_HORIZONTAL_ABS: - wrapperClass = [DOMSVGPathSegLinetoHorizontalAbs class]; - break; + return [DOMSVGPathSegLinetoHorizontalAbs class]; case WebCore::SVGPathSeg::PATHSEG_LINETO_HORIZONTAL_REL: - wrapperClass = [DOMSVGPathSegLinetoHorizontalRel class]; - break; + return [DOMSVGPathSegLinetoHorizontalRel class]; case WebCore::SVGPathSeg::PATHSEG_LINETO_VERTICAL_ABS: - wrapperClass = [DOMSVGPathSegLinetoVerticalAbs class]; - break; + return [DOMSVGPathSegLinetoVerticalAbs class]; case WebCore::SVGPathSeg::PATHSEG_LINETO_VERTICAL_REL: - wrapperClass = [DOMSVGPathSegLinetoVerticalRel class]; - break; + return [DOMSVGPathSegLinetoVerticalRel class]; case WebCore::SVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_ABS: - wrapperClass = [DOMSVGPathSegCurvetoCubicSmoothAbs class]; - break; + return [DOMSVGPathSegCurvetoCubicSmoothAbs class]; case WebCore::SVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_REL: - wrapperClass = [DOMSVGPathSegCurvetoCubicSmoothRel class]; - break; + return [DOMSVGPathSegCurvetoCubicSmoothRel class]; case WebCore::SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS: - wrapperClass = [DOMSVGPathSegCurvetoQuadraticSmoothAbs class]; - break; + return [DOMSVGPathSegCurvetoQuadraticSmoothAbs class]; case WebCore::SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL: - wrapperClass = [DOMSVGPathSegCurvetoQuadraticSmoothRel class]; - break; + return [DOMSVGPathSegCurvetoQuadraticSmoothRel class]; } - - return [[[wrapperClass alloc] _initWithSVGPathSeg:impl] autorelease]; + ASSERT_NOT_REACHED(); + return nil; } -@end - #endif // ENABLE(SVG) diff --git a/WebCore/bindings/objc/DOMUtility.mm b/WebCore/bindings/objc/DOMUtility.mm index e346c9e..2b8c474 100644 --- a/WebCore/bindings/objc/DOMUtility.mm +++ b/WebCore/bindings/objc/DOMUtility.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2006 James G. Speth (speth@end.com) * * Redistribution and use in source and binary forms, with or without @@ -26,8 +26,27 @@ #import "config.h" +#import "DOMAbstractViewInternal.h" +#import "DOMCSSRuleInternal.h" +#import "DOMCSSRuleListInternal.h" +#import "DOMCSSStyleDeclarationInternal.h" +#import "DOMCSSValueInternal.h" +#import "DOMCounterInternal.h" +#import "DOMEventInternal.h" +#import "DOMHTMLCollectionInternal.h" #import "DOMImplementationFront.h" #import "DOMInternal.h" +#import "DOMMediaListInternal.h" +#import "DOMNamedNodeMapInternal.h" +#import "DOMNodeInternal.h" +#import "DOMNodeIteratorInternal.h" +#import "DOMNodeListInternal.h" +#import "DOMRGBColorInternal.h" +#import "DOMRangeInternal.h" +#import "DOMRectInternal.h" +#import "DOMStyleSheetInternal.h" +#import "DOMStyleSheetListInternal.h" +#import "DOMTreeWalkerInternal.h" #import "JSCSSRule.h" #import "JSCSSRuleList.h" #import "JSCSSStyleDeclaration.h" @@ -52,20 +71,25 @@ #import "JSTreeWalker.h" #import "JSXPathExpression.h" #import "JSXPathResult.h" -#import "Node.h" #import "WebScriptObjectPrivate.h" #import "runtime_root.h" -#import <objc/objc-runtime.h> + +#if ENABLE(XPATH) +#import "DOMXPathExpressionInternal.h" +#import "DOMXPathResultInternal.h" +#endif + +// FIXME: Couldn't get an include of "DOMDOMImplementationInternal.h" to work here. +DOMImplementation *kit(WebCore::DOMImplementationFront*); // This file makes use of both the ObjC DOM API and the C++ DOM API, so we need to be careful about what // headers are included and what namespaces we use to avoid naming conflicts. -// FIXME: This has to be in the KJS namespace to avoid an Objective-C++ ambiguity with C++ and -// Objective-C classes of the same name (even when not in the same namespace). That's also the -// reason for the use of objc_getClass in the WRAP_OLD macro below. +// FIXME: This has to be in the JSC namespace to avoid an Objective-C++ ambiguity with C++ and +// Objective-C classes of the same name (even when not in the same namespace). // Some day if the compiler is fixed, or if all the JS wrappers are named with a "JS" prefix, -// we could move the function into the WebCore namespace where it belongs. +// we could move the function out of the JSC namespace. namespace JSC { @@ -73,7 +97,7 @@ static inline id createDOMWrapper(JSC::JSObject* object) { #define WRAP(className) \ if (object->inherits(&WebCore::JS##className::s_info)) \ - return [DOM##className _wrap##className:static_cast<WebCore::JS##className*>(object)->impl()]; + return kit(static_cast<WebCore::JS##className*>(object)->impl()); WRAP(CSSRule) WRAP(CSSRuleList) @@ -105,18 +129,16 @@ static inline id createDOMWrapper(JSC::JSObject* object) #undef WRAP if (object->inherits(&WebCore::JSDOMWindowShell::s_info)) - return [DOMAbstractView _wrapAbstractView:static_cast<WebCore::JSDOMWindowShell*>(object)->impl()]; + return kit(static_cast<WebCore::JSDOMWindowShell*>(object)->impl()); if (object->inherits(&WebCore::JSDOMImplementation::s_info)) - return [DOMImplementation _wrapDOMImplementation:implementationFront(static_cast<WebCore::JSDOMImplementation*>(object))]; + return kit(implementationFront(static_cast<WebCore::JSDOMImplementation*>(object))); return nil; } } -namespace WebCore { - id createDOMWrapper(JSC::JSObject* object, PassRefPtr<JSC::Bindings::RootObject> origin, PassRefPtr<JSC::Bindings::RootObject> current) { id wrapper = JSC::createDOMWrapper(object); @@ -124,5 +146,3 @@ id createDOMWrapper(JSC::JSObject* object, PassRefPtr<JSC::Bindings::RootObject> [wrapper _setImp:object originRootObject:origin rootObject:current]; return wrapper; } - -} diff --git a/WebCore/bindings/objc/DOMXPath.mm b/WebCore/bindings/objc/DOMXPath.mm index 0d008f1..d1c07d7 100644 --- a/WebCore/bindings/objc/DOMXPath.mm +++ b/WebCore/bindings/objc/DOMXPath.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2006, 2009 Apple Inc. All rights reserved. * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com> * * Redistribution and use in source and binary forms, with or without @@ -28,10 +28,11 @@ #if ENABLE(XPATH) +#import "DOMInternal.h" // import first to make the private/public trick work #import "DOMXPath.h" -#import "DOMInternal.h" #import "PlatformString.h" +#import "WebScriptObjectPrivate.h" #import "XPathNSResolver.h" //------------------------------------------------------------------------------------------ @@ -55,40 +56,31 @@ [super finalize]; } -- (WebCore::XPathNSResolver *)_xpathNSResolver +- (NSString *)lookupNamespaceURI:(NSString *)prefix { - return IMPL; + return IMPL->lookupNamespaceURI(prefix); } -- (id)_initWithXPathNSResolver:(WebCore::XPathNSResolver *)impl +@end + +WebCore::XPathNSResolver* core(DOMNativeXPathNSResolver *wrapper) { - ASSERT(impl); - - [super _init]; - _internal = reinterpret_cast<DOMObjectInternal*>(impl); - impl->ref(); - WebCore::addDOMWrapper(self, impl); - return self; + return wrapper ? reinterpret_cast<WebCore::XPathNSResolver*>(wrapper->_internal) : 0; } -+ (DOMNativeXPathNSResolver *)_wrapXPathNSResolver:(WebCore::XPathNSResolver *)impl +DOMNativeXPathNSResolver *kit(WebCore::XPathNSResolver* impl) { if (!impl) return nil; - id cachedInstance; - cachedInstance = WebCore::getDOMWrapper(impl); - if (cachedInstance) - return [[cachedInstance retain] autorelease]; + if (DOMNativeXPathNSResolver *wrapper = getDOMWrapper(impl)) + return [[wrapper retain] autorelease]; - return [[[DOMNativeXPathNSResolver alloc] _initWithXPathNSResolver:impl] autorelease]; -} - -- (NSString *)lookupNamespaceURI:(NSString *)prefix -{ - return IMPL->lookupNamespaceURI(prefix); + DOMNativeXPathNSResolver *wrapper = [[DOMNativeXPathNSResolver alloc] _init]; + wrapper->_internal = reinterpret_cast<DOMObjectInternal*>(impl); + impl->ref(); + addDOMWrapper(wrapper, impl); + return [wrapper autorelease]; } -@end - #endif // ENABLE(XPATH) diff --git a/WebCore/bindings/objc/ExceptionHandlers.mm b/WebCore/bindings/objc/ExceptionHandlers.mm index e9e42a8..96ba2c9 100644 --- a/WebCore/bindings/objc/ExceptionHandlers.mm +++ b/WebCore/bindings/objc/ExceptionHandlers.mm @@ -28,11 +28,14 @@ #include "ExceptionCode.h" -NSString * DOMException = @"DOMException"; -NSString * DOMRangeException = @"DOMRangeException"; -NSString * DOMEventException = @"DOMEventException"; -NSString * DOMSVGException = @"DOMSVGException"; -NSString * DOMXPathException = @"DOMXPathException"; +NSString *DOMException = @"DOMException"; +NSString *DOMRangeException = @"DOMRangeException"; +NSString *DOMEventException = @"DOMEventException"; +NSString *DOMXPathException = @"DOMXPathException"; + +#if ENABLE(SVG_DOM_OBJC_BINDINGS) +NSString *DOMSVGException = @"DOMSVGException"; +#endif namespace WebCore { @@ -48,8 +51,10 @@ void raiseDOMException(ExceptionCode ec) exceptionName = DOMRangeException; else if (strcmp(description.typeName, "DOM Events") == 0) exceptionName = DOMEventException; +#if ENABLE(SVG_DOM_OBJC_BINDINGS) else if (strcmp(description.typeName, "DOM SVG") == 0) exceptionName = DOMSVGException; +#endif else if (strcmp(description.typeName, "DOM XPath") == 0) exceptionName = DOMXPathException; else diff --git a/WebCore/bindings/objc/ObjCEventListener.mm b/WebCore/bindings/objc/ObjCEventListener.mm index 46c04c1..77c6ad2 100644 --- a/WebCore/bindings/objc/ObjCEventListener.mm +++ b/WebCore/bindings/objc/ObjCEventListener.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2006 James G. Speth (speth@end.com) * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) * @@ -26,15 +26,12 @@ */ #import "config.h" - #import "ObjCEventListener.h" #import "DOMEventInternal.h" #import "DOMEventListener.h" #import "Event.h" #import "EventListener.h" - -#import <objc/objc-class.h> #import <wtf/HashMap.h> namespace WebCore { @@ -44,9 +41,10 @@ static ListenerMap* listenerMap; ObjCEventListener* ObjCEventListener::find(id <DOMEventListener> listener) { - if (ListenerMap* map = listenerMap) - return map->get(listener); - return 0; + ListenerMap* map = listenerMap; + if (!map) + return 0; + return map->get(listener); } PassRefPtr<ObjCEventListener> ObjCEventListener::wrap(id <DOMEventListener> listener) @@ -76,7 +74,7 @@ ObjCEventListener::~ObjCEventListener() void ObjCEventListener::handleEvent(Event* event, bool) { - [m_listener handleEvent:[DOMEvent _wrapEvent:event]]; + [m_listener handleEvent:kit(event)]; } } // namespace WebCore diff --git a/WebCore/bindings/objc/ObjCNodeFilterCondition.mm b/WebCore/bindings/objc/ObjCNodeFilterCondition.mm index 982cfe0..825c247 100644 --- a/WebCore/bindings/objc/ObjCNodeFilterCondition.mm +++ b/WebCore/bindings/objc/ObjCNodeFilterCondition.mm @@ -41,7 +41,7 @@ short ObjCNodeFilterCondition::acceptNode(ExecState*, Node* node) const { if (!node) return NodeFilter::FILTER_REJECT; - return [m_filter.get() acceptNode:[DOMNode _wrapNode:node]]; + return [m_filter.get() acceptNode:kit(node)]; } } // namespace WebCore diff --git a/WebCore/bindings/objc/PublicDOMInterfaces.h b/WebCore/bindings/objc/PublicDOMInterfaces.h index 349abaf..9221037 100644 --- a/WebCore/bindings/objc/PublicDOMInterfaces.h +++ b/WebCore/bindings/objc/PublicDOMInterfaces.h @@ -91,6 +91,18 @@ @property(readonly, copy) NSString *URL; @property(retain) DOMHTMLElement *body; @property(copy) NSString *cookie; +@property(readonly, copy) NSString *inputEncoding AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *xmlEncoding AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(copy) NSString *xmlVersion AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property BOOL xmlStandalone AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(copy) NSString *documentURI AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(copy) NSString *charset AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *defaultCharset AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *readyState AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *characterSet AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *preferredStylesheetSet AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(copy) NSString *selectedStylesheetSet AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *lastModified AVAILABLE_IN_WEBKIT_VERSION_4_0; - (DOMElement *)createElement:(NSString *)tagName; - (DOMDocumentFragment *)createDocumentFragment; - (DOMText *)createTextNode:(NSString *)data; @@ -132,6 +144,18 @@ - (DOMXPathResult *)evaluate:(NSString *)expression :(DOMNode *)contextNode :(id <DOMXPathNSResolver>)resolver :(unsigned short)type :(DOMXPathResult *)inResult AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED; - (DOMXPathResult *)evaluate:(NSString *)expression contextNode:(DOMNode *)contextNode resolver:(id <DOMXPathNSResolver>)resolver type:(unsigned short)type inResult:(DOMXPathResult *)inResult AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; #endif +- (BOOL)execCommand:(NSString *)command userInterface:(BOOL)userInterface value:(NSString *)value AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (BOOL)execCommand:(NSString *)command userInterface:(BOOL)userInterface AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (BOOL)execCommand:(NSString *)command AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (BOOL)queryCommandEnabled:(NSString *)command AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (BOOL)queryCommandIndeterm:(NSString *)command AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (BOOL)queryCommandState:(NSString *)command AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (BOOL)queryCommandSupported:(NSString *)command AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (NSString *)queryCommandValue:(NSString *)command AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (DOMElement *)elementFromPoint:(int)x y:(int)y AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (DOMNodeList *)getElementsByClassName:(NSString *)tagname AVAILABLE_IN_WEBKIT_VERSION_4_0; +- (DOMElement *)querySelector:(NSString *)selectors AVAILABLE_IN_WEBKIT_VERSION_4_0; +- (DOMNodeList *)querySelectorAll:(NSString *)selectors AVAILABLE_IN_WEBKIT_VERSION_4_0; @end @interface DOMDocumentFragment : DOMNode WEBKIT_VERSION_1_3 @@ -160,6 +184,14 @@ @property int scrollTop; @property(readonly) int scrollWidth; @property(readonly) int scrollHeight; +@property(readonly) int clientLeft AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int clientTop AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *innerText AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, retain) DOMElement *firstElementChild AVAILABLE_IN_WEBKIT_VERSION_4_0; +@property(readonly, retain) DOMElement *lastElementChild AVAILABLE_IN_WEBKIT_VERSION_4_0; +@property(readonly, retain) DOMElement *previousElementSibling AVAILABLE_IN_WEBKIT_VERSION_4_0; +@property(readonly, retain) DOMElement *nextElementSibling AVAILABLE_IN_WEBKIT_VERSION_4_0; +@property(readonly) unsigned childElementCount AVAILABLE_IN_WEBKIT_VERSION_4_0; - (NSString *)getAttribute:(NSString *)name; - (void)setAttribute:(NSString *)name :(NSString *)value; - (void)setAttribute:(NSString *)name value:(NSString *)value AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; @@ -184,6 +216,14 @@ - (BOOL)hasAttributeNS:(NSString *)namespaceURI localName:(NSString *)localName AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; - (void)scrollIntoView:(BOOL)alignWithTop AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; - (void)scrollIntoViewIfNeeded:(BOOL)centerIfNeeded AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (BOOL)contains:(DOMElement *)element AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (void)scrollByLines:(int)lines AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (void)scrollByPages:(int)pages AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (void)focus AVAILABLE_IN_WEBKIT_VERSION_4_0; +- (void)blur AVAILABLE_IN_WEBKIT_VERSION_4_0; +- (DOMNodeList *)getElementsByClassName:(NSString *)name AVAILABLE_IN_WEBKIT_VERSION_4_0; +- (DOMElement *)querySelector:(NSString *)selectors AVAILABLE_IN_WEBKIT_VERSION_4_0; +- (DOMNodeList *)querySelectorAll:(NSString *)selectors AVAILABLE_IN_WEBKIT_VERSION_4_0; @end @interface DOMEntity : DOMNode WEBKIT_VERSION_1_3 @@ -195,6 +235,16 @@ @interface DOMEntityReference : DOMNode WEBKIT_VERSION_1_3 @end +@interface DOMFile : DOMObject WEBKIT_VERSION_4_0 +@property(readonly, copy) NSString *fileName; +@property(readonly) unsigned long long fileSize; +@end + +@interface DOMFileList : DOMObject WEBKIT_VERSION_4_0 +@property(readonly) unsigned length; +- (DOMFile *)item:(unsigned)index; +@end + @interface DOMNamedNodeMap : DOMObject WEBKIT_VERSION_1_3 @property(readonly) unsigned length; - (DOMNode *)getNamedItem:(NSString *)name; @@ -224,6 +274,9 @@ @property(copy) NSString *prefix; @property(readonly, copy) NSString *localName; @property(copy) NSString *textContent AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *baseURI AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, retain) DOMElement *parentElement AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) BOOL isContentEditable AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; - (DOMNode *)insertBefore:(DOMNode *)newChild :(DOMNode *)refChild; - (DOMNode *)insertBefore:(DOMNode *)newChild refChild:(DOMNode *)refChild AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; - (DOMNode *)replaceChild:(DOMNode *)newChild :(DOMNode *)oldChild; @@ -238,6 +291,10 @@ - (BOOL)hasAttributes; - (BOOL)isSameNode:(DOMNode *)other AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; - (BOOL)isEqualNode:(DOMNode *)other AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (NSString *)lookupPrefix:(NSString *)namespaceURI AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (BOOL)isDefaultNamespace:(NSString *)namespaceURI AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (NSString *)lookupNamespaceURI:(NSString *)prefix AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (unsigned short)compareDocumentPosition:(DOMNode *)other AVAILABLE_IN_WEBKIT_VERSION_4_0; @end @interface DOMNodeList : DOMObject WEBKIT_VERSION_1_3 @@ -253,10 +310,13 @@ @interface DOMProcessingInstruction : DOMNode WEBKIT_VERSION_1_3 @property(readonly, copy) NSString *target; @property(copy) NSString *data; +@property(readonly, retain) DOMStyleSheet *sheet AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; @end @interface DOMText : DOMCharacterData WEBKIT_VERSION_1_3 +@property(readonly, copy) NSString *wholeText AVAILABLE_IN_WEBKIT_VERSION_4_0; - (DOMText *)splitText:(unsigned)offset; +- (DOMText *)replaceWholeText:(NSString *)content AVAILABLE_IN_WEBKIT_VERSION_4_0; @end @interface DOMHTMLAnchorElement : DOMHTMLElement WEBKIT_VERSION_1_3 @@ -272,6 +332,14 @@ @property(copy) NSString *target; @property(copy) NSString *type; @property(readonly, copy) NSURL *absoluteLinkURL AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *hashName AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *host AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *hostname AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *pathname AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *port AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *protocol AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *search AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *text AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; @end @interface DOMHTMLAppletElement : DOMHTMLElement WEBKIT_VERSION_1_3 @@ -297,6 +365,13 @@ @property(copy) NSString *shape; @property(copy) NSString *target; @property(readonly, copy) NSURL *absoluteLinkURL AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *hashName AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *host AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *hostname AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *pathname AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *port AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *protocol AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, copy) NSString *search AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; @end @interface DOMHTMLBRElement : DOMHTMLElement WEBKIT_VERSION_1_3 @@ -330,6 +405,9 @@ @property(copy) NSString *name; @property(readonly, copy) NSString *type; @property(copy) NSString *value; +@property BOOL autofocus AVAILABLE_IN_WEBKIT_VERSION_4_0; +@property(readonly) BOOL willValidate AVAILABLE_IN_WEBKIT_VERSION_4_0; +- (void)click AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; @end @interface DOMHTMLCanvasElement : DOMHTMLElement WEBKIT_VERSION_3_0 @@ -341,6 +419,7 @@ @property(readonly) unsigned length; - (DOMNode *)item:(unsigned)index; - (DOMNode *)namedItem:(NSString *)name; +- (DOMNodeList *)tags:(NSString *)name AVAILABLE_IN_WEBKIT_VERSION_4_0; @end @interface DOMHTMLDListElement : DOMHTMLElement WEBKIT_VERSION_1_3 @@ -356,6 +435,24 @@ @end @interface DOMHTMLDocument : DOMDocument WEBKIT_VERSION_1_3 +@property(readonly, retain) DOMHTMLCollection *embeds AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, retain) DOMHTMLCollection *plugins AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, retain) DOMHTMLCollection *scripts AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int width AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int height AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(copy) NSString *dir AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(copy) NSString *designMode AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(copy) NSString *bgColor AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(copy) NSString *fgColor AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(copy) NSString *alinkColor AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(copy) NSString *linkColor AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(copy) NSString *vlinkColor AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, retain) DOMElement *activeElement AVAILABLE_IN_WEBKIT_VERSION_4_0; +@property(readonly, copy) NSString *compatMode AVAILABLE_IN_WEBKIT_VERSION_4_0; +- (void)captureEvents AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (void)releaseEvents AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (void)clear AVAILABLE_IN_WEBKIT_VERSION_4_0; +- (BOOL)hasFocus AVAILABLE_IN_WEBKIT_VERSION_4_0; - (void)open; - (void)close; - (void)write:(NSString *)text; @@ -377,8 +474,6 @@ @property(readonly) BOOL isContentEditable; @property(readonly, copy) NSString *titleDisplayString AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; @property int tabIndex; -- (void)blur; -- (void)focus; @end @interface DOMHTMLEmbedElement : DOMHTMLElement WEBKIT_VERSION_1_3 @@ -409,6 +504,7 @@ @property(copy) NSString *enctype; @property(copy) NSString *method; @property(copy) NSString *target; +@property(copy) NSString *encoding AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; - (void)submit; - (void)reset; @end @@ -423,6 +519,10 @@ @property(copy) NSString *scrolling; @property(copy) NSString *src; @property(readonly, retain) DOMDocument *contentDocument; +@property(readonly, retain) DOMAbstractView *contentWindow AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(copy) NSString *location AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int width AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int height AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; @end @interface DOMHTMLFrameSetElement : DOMHTMLElement WEBKIT_VERSION_1_3 @@ -461,6 +561,7 @@ @property(copy) NSString *src; @property(copy) NSString *width; @property(readonly, retain) DOMDocument *contentDocument; +@property(readonly, retain) DOMAbstractView *contentWindow AVAILABLE_IN_WEBKIT_VERSION_4_0; @end @interface DOMHTMLImageElement : DOMHTMLElement WEBKIT_VERSION_1_3 @@ -478,6 +579,12 @@ @property int width; @property(readonly, copy) NSString *altDisplayString AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; @property(readonly, copy) NSURL *absoluteImageURL AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) BOOL complete AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(copy) NSString *lowsrc AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int naturalHeight AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int naturalWidth AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int x AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int y AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; @end @interface DOMHTMLInputElement : DOMHTMLElement WEBKIT_VERSION_1_3 @@ -500,8 +607,16 @@ @property(copy) NSString *value; @property(readonly, copy) NSString *altDisplayString AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; @property(readonly, copy) NSURL *absoluteImageURL AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property BOOL indeterminate AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property int selectionStart AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property int selectionEnd AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property BOOL autofocus AVAILABLE_IN_WEBKIT_VERSION_4_0; +@property BOOL multiple AVAILABLE_IN_WEBKIT_VERSION_4_0; +@property(readonly) BOOL willValidate AVAILABLE_IN_WEBKIT_VERSION_4_0; +@property(readonly, retain) DOMFileList *files AVAILABLE_IN_WEBKIT_VERSION_4_0; - (void)select; - (void)click; +- (void)setSelectionRange:(int)start end:(int)end AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; @end @interface DOMHTMLIsIndexElement : DOMHTMLInputElement WEBKIT_VERSION_1_3 @@ -537,6 +652,7 @@ @property(copy) NSString *target; @property(copy) NSString *type; @property(readonly, copy) NSURL *absoluteLinkURL AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, retain) DOMStyleSheet *sheet AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; @end @interface DOMHTMLMapElement : DOMHTMLElement WEBKIT_VERSION_1_3 @@ -611,8 +727,11 @@ @interface DOMHTMLOptionsCollection : DOMObject WEBKIT_VERSION_1_3 @property unsigned length; +@property int selectedIndex AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; - (DOMNode *)item:(unsigned)index; - (DOMNode *)namedItem:(NSString *)name; +- (void)add:(DOMHTMLOptionElement *)option index:(unsigned)index AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (void)remove:(unsigned)index AVAILABLE_IN_WEBKIT_VERSION_4_0; @end @interface DOMHTMLParagraphElement : DOMHTMLElement WEBKIT_VERSION_1_3 @@ -628,6 +747,7 @@ @interface DOMHTMLPreElement : DOMHTMLElement WEBKIT_VERSION_1_3 @property int width; +@property BOOL wrap AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; @end @interface DOMHTMLQuoteElement : DOMHTMLElement WEBKIT_VERSION_1_3 @@ -655,15 +775,20 @@ @property BOOL multiple; @property(copy) NSString *name; @property int size; +@property(readonly) BOOL willValidate AVAILABLE_IN_WEBKIT_VERSION_4_0; +@property BOOL autofocus AVAILABLE_IN_WEBKIT_VERSION_4_0; - (void)add:(DOMHTMLElement *)element :(DOMHTMLElement *)before; - (void)add:(DOMHTMLElement *)element before:(DOMHTMLElement *)before AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; - (void)remove:(int)index; +- (DOMNode *)item:(unsigned)index AVAILABLE_IN_WEBKIT_VERSION_4_0; +- (DOMNode *)namedItem:(NSString *)name AVAILABLE_IN_WEBKIT_VERSION_4_0; @end @interface DOMHTMLStyleElement : DOMHTMLElement WEBKIT_VERSION_1_3 @property BOOL disabled; @property(copy) NSString *media; @property(copy) NSString *type; +@property(readonly, retain) DOMStyleSheet *sheet AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; @end @interface DOMHTMLTableCaptionElement : DOMHTMLElement WEBKIT_VERSION_1_3 @@ -756,7 +881,12 @@ @property int rows; @property(readonly, copy) NSString *type; @property(copy) NSString *value; +@property int selectionStart AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property int selectionEnd AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property BOOL autofocus AVAILABLE_IN_WEBKIT_VERSION_4_0; +@property(readonly) BOOL willValidate AVAILABLE_IN_WEBKIT_VERSION_4_0; - (void)select; +- (void)setSelectionRange:(int)start end:(int)end AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; @end @interface DOMHTMLTitleElement : DOMHTMLElement WEBKIT_VERSION_1_3 @@ -866,9 +996,12 @@ @interface DOMCSSStyleSheet : DOMStyleSheet WEBKIT_VERSION_1_3 @property(readonly, retain) DOMCSSRule *ownerRule; @property(readonly, retain) DOMCSSRuleList *cssRules; +@property(readonly, retain) DOMCSSRuleList *rules AVAILABLE_IN_WEBKIT_VERSION_4_0; - (unsigned)insertRule:(NSString *)rule :(unsigned)index; - (unsigned)insertRule:(NSString *)rule index:(unsigned)index AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; - (void)deleteRule:(unsigned)index; +- (int)addRule:(NSString *)selector style:(NSString *)style index:(unsigned)index AVAILABLE_IN_WEBKIT_VERSION_4_0; +- (void)removeRule:(unsigned)index AVAILABLE_IN_WEBKIT_VERSION_4_0; @end @interface DOMCSSValue : DOMObject WEBKIT_VERSION_1_3 @@ -905,6 +1038,9 @@ @property(readonly) BOOL bubbles; @property(readonly) BOOL cancelable; @property(readonly) DOMTimeStamp timeStamp; +@property(readonly, retain) id <DOMEventTarget> srcElement AVAILABLE_IN_WEBKIT_VERSION_4_0; +@property BOOL returnValue AVAILABLE_IN_WEBKIT_VERSION_4_0; +@property BOOL cancelBubble AVAILABLE_IN_WEBKIT_VERSION_4_0; - (void)stopPropagation; - (void)preventDefault; - (void)initEvent:(NSString *)eventTypeArg canBubbleArg:(BOOL)canBubbleArg cancelableArg:(BOOL)cancelableArg AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; @@ -914,6 +1050,13 @@ @interface DOMUIEvent : DOMEvent WEBKIT_VERSION_1_3 @property(readonly, retain) DOMAbstractView *view; @property(readonly) int detail; +@property(readonly) int keyCode AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int charCode AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int layerX AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int layerY AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int pageX AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int pageY AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int which AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; - (void)initUIEvent:(NSString *)type canBubble:(BOOL)canBubble cancelable:(BOOL)cancelable view:(DOMAbstractView *)view detail:(int)detail AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; - (void)initUIEvent:(NSString *)type :(BOOL)canBubble :(BOOL)cancelable :(DOMAbstractView *)view :(int)detail; @end @@ -946,6 +1089,13 @@ @property(readonly) BOOL metaKey; @property(readonly) BOOL isHorizontal; @property(readonly) int wheelDelta; +@property(readonly) int wheelDeltaX AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int wheelDeltaY AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int offsetX AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int offsetY AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int x AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int y AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (void)initWheelEvent:(int)wheelDeltaX wheelDeltaY:(int)wheelDeltaY view:(DOMAbstractView *)view screenX:(int)screenX screenY:(int)screenY clientX:(int)clientX clientY:(int)clientY ctrlKey:(BOOL)ctrlKey altKey:(BOOL)altKey shiftKey:(BOOL)shiftKey metaKey:(BOOL)metaKey AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; @end @interface DOMKeyboardEvent : DOMUIEvent WEBKIT_VERSION_3_0 @@ -957,7 +1107,10 @@ @property(readonly) BOOL metaKey; @property(readonly) int keyCode; @property(readonly) int charCode; +@property(readonly) BOOL altGraphKey AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; - (BOOL)getModifierState:(NSString *)keyIdentifierArg; +- (void)initKeyboardEvent:(NSString *)type canBubble:(BOOL)canBubble cancelable:(BOOL)cancelable view:(DOMAbstractView *)view keyIdentifier:(NSString *)keyIdentifier keyLocation:(unsigned)keyLocation ctrlKey:(BOOL)ctrlKey altKey:(BOOL)altKey shiftKey:(BOOL)shiftKey metaKey:(BOOL)metaKey altGraphKey:(BOOL)altGraphKey AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (void)initKeyboardEvent:(NSString *)type canBubble:(BOOL)canBubble cancelable:(BOOL)cancelable view:(DOMAbstractView *)view keyIdentifier:(NSString *)keyIdentifier keyLocation:(unsigned)keyLocation ctrlKey:(BOOL)ctrlKey altKey:(BOOL)altKey shiftKey:(BOOL)shiftKey metaKey:(BOOL)metaKey AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; @end @interface DOMMouseEvent : DOMUIEvent WEBKIT_VERSION_1_3 @@ -971,6 +1124,12 @@ @property(readonly) BOOL metaKey; @property(readonly) unsigned short button; @property(readonly, retain) id <DOMEventTarget> relatedTarget; +@property(readonly) int offsetX AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int offsetY AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int x AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) int y AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, retain) DOMNode *fromElement AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly, retain) DOMNode *toElement AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; - (void)initMouseEvent:(NSString *)type canBubble:(BOOL)canBubble cancelable:(BOOL)cancelable view:(DOMAbstractView *)view detail:(int)detail screenX:(int)screenX screenY:(int)screenY clientX:(int)clientX clientY:(int)clientY ctrlKey:(BOOL)ctrlKey altKey:(BOOL)altKey shiftKey:(BOOL)shiftKey metaKey:(BOOL)metaKey button:(unsigned short)button relatedTarget:(id <DOMEventTarget>)relatedTarget AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; - (void)initMouseEvent:(NSString *)type :(BOOL)canBubble :(BOOL)cancelable :(DOMAbstractView *)view :(int)detail :(int)screenX :(int)screenY :(int)clientX :(int)clientY :(BOOL)ctrlKey :(BOOL)altKey :(BOOL)shiftKey :(BOOL)metaKey :(unsigned short)button :(id <DOMEventTarget>)relatedTarget; @end @@ -1004,6 +1163,11 @@ - (DOMRange *)cloneRange; - (NSString *)toString; - (void)detach; +- (DOMDocumentFragment *)createContextualFragment:(NSString *)html AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (BOOL)intersectsNode:(DOMNode *)refNode AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (short)compareNode:(DOMNode *)refNode AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (short)comparePoint:(DOMNode *)refNode offset:(int)offset AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (BOOL)isPointInRange:(DOMNode *)refNode offset:(int)offset AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; @end @interface DOMNodeIterator : DOMObject WEBKIT_VERSION_1_3 @@ -1011,6 +1175,8 @@ @property(readonly) unsigned whatToShow; @property(readonly, retain) id <DOMNodeFilter> filter; @property(readonly) BOOL expandEntityReferences; +@property(readonly, retain) DOMNode *referenceNode AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +@property(readonly) BOOL pointerBeforeReferenceNode AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; - (DOMNode *)nextNode; - (DOMNode *)previousNode; - (void)detach; diff --git a/WebCore/bindings/objc/WebScriptObject.mm b/WebCore/bindings/objc/WebScriptObject.mm index 3cdae86..8889eac 100644 --- a/WebCore/bindings/objc/WebScriptObject.mm +++ b/WebCore/bindings/objc/WebScriptObject.mm @@ -113,7 +113,7 @@ static void addExceptionToConsole(ExecState* exec) + (id)scriptObjectForJSObject:(JSObjectRef)jsObject originRootObject:(RootObject*)originRootObject rootObject:(RootObject*)rootObject { - if (id domWrapper = WebCore::createDOMWrapper(toJS(jsObject), originRootObject, rootObject)) + if (id domWrapper = createDOMWrapper(toJS(jsObject), originRootObject, rootObject)) return domWrapper; return WebCore::createJSWrapper(toJS(jsObject), originRootObject, rootObject); @@ -265,7 +265,7 @@ static void _didExecute(WebScriptObject *obj) return YES; } -static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* rootObject, ArgList& aList) +static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* rootObject, MarkedArgumentBuffer& aList) { int i, numObjects = array ? [array count] : 0; @@ -286,20 +286,20 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root ExecState* exec = [self _rootObject]->globalObject()->globalExec(); ASSERT(!exec->hadException()); - JSValuePtr function = [self _imp]->get(exec, Identifier(exec, String(name))); + JSValue function = [self _imp]->get(exec, Identifier(exec, String(name))); CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) return nil; - ArgList argList; + MarkedArgumentBuffer argList; getListFromNSArray(exec, args, [self _rootObject], argList); if (![self _isSafeScript]) return nil; [self _rootObject]->globalObject()->globalData()->timeoutChecker.start(); - JSValuePtr result = call(exec, function, callType, callData, [self _imp], argList); + JSValue result = call(exec, function, callType, callData, [self _imp], argList); [self _rootObject]->globalObject()->globalData()->timeoutChecker.stop(); if (exec->hadException()) { @@ -324,7 +324,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root ExecState* exec = [self _rootObject]->globalObject()->globalExec(); ASSERT(!exec->hadException()); - JSValuePtr result; + JSValue result; JSLock lock(false); [self _rootObject]->globalObject()->globalData()->timeoutChecker.start(); @@ -388,7 +388,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root // leaving the lock permanently held JSLock lock(false); - JSValuePtr result = [self _imp]->get(exec, Identifier(exec, String(key))); + JSValue result = [self _imp]->get(exec, Identifier(exec, String(key))); if (exec->hadException()) { addExceptionToConsole(exec); @@ -455,7 +455,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root ASSERT(!exec->hadException()); JSLock lock(false); - JSValuePtr result = [self _imp]->get(exec, index); + JSValue result = [self _imp]->get(exec, index); if (exec->hadException()) { addExceptionToConsole(exec); @@ -504,7 +504,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root return toRef([self _imp]); } -+ (id)_convertValueToObjcValue:(JSValuePtr)value originRootObject:(RootObject*)originRootObject rootObject:(RootObject*)rootObject ++ (id)_convertValueToObjcValue:(JSValue)value originRootObject:(RootObject*)originRootObject rootObject:(RootObject*)rootObject { if (value.isObject()) { JSObject* object = asObject(value); @@ -512,7 +512,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root JSLock lock(false); if (object->classInfo() != &RuntimeObjectImp::s_info) { - JSValuePtr runtimeObject = object->get(exec, Identifier(exec, "__apple_runtime_object")); + JSValue runtimeObject = object->get(exec, Identifier(exec, "__apple_runtime_object")); if (runtimeObject && runtimeObject.isObject()) object = asObject(runtimeObject); } diff --git a/WebCore/bindings/objc/WebScriptObjectPrivate.h b/WebCore/bindings/objc/WebScriptObjectPrivate.h index 6810de6..3a424ce 100644 --- a/WebCore/bindings/objc/WebScriptObjectPrivate.h +++ b/WebCore/bindings/objc/WebScriptObjectPrivate.h @@ -46,7 +46,7 @@ namespace WebCore { } @interface WebScriptObject (Private) -+ (id)_convertValueToObjcValue:(JSC::JSValuePtr)value originRootObject:(JSC::Bindings::RootObject*)originRootObject rootObject:(JSC::Bindings::RootObject*)rootObject; ++ (id)_convertValueToObjcValue:(JSC::JSValue)value originRootObject:(JSC::Bindings::RootObject*)originRootObject rootObject:(JSC::Bindings::RootObject*)rootObject; + (id)scriptObjectForJSObject:(JSObjectRef)jsObject originRootObject:(JSC::Bindings::RootObject*)originRootObject rootObject:(JSC::Bindings::RootObject*)rootObject; - (id)_init; - (id)_initWithJSObject:(JSC::JSObject*)imp originRootObject:(PassRefPtr<JSC::Bindings::RootObject>)originRootObject rootObject:(PassRefPtr<JSC::Bindings::RootObject>)rootObject; diff --git a/WebCore/bindings/scripts/CodeGenerator.pm b/WebCore/bindings/scripts/CodeGenerator.pm index 4f899be..d217c37 100644 --- a/WebCore/bindings/scripts/CodeGenerator.pm +++ b/WebCore/bindings/scripts/CodeGenerator.pm @@ -381,6 +381,8 @@ sub WK_lcfirst my $ret = lcfirst($param); $ret =~ s/uRL/url/ if $ret =~ /^uRL/; $ret =~ s/jS/js/ if $ret =~ /^jS/; + $ret =~ s/xML/xml/ if $ret =~ /^xML/; + $ret =~ s/xSLT/xslt/ if $ret =~ /^xSLT/; return $ret; } diff --git a/WebCore/bindings/scripts/CodeGeneratorCOM.pm b/WebCore/bindings/scripts/CodeGeneratorCOM.pm index 4e363aa..7e80a17 100644 --- a/WebCore/bindings/scripts/CodeGeneratorCOM.pm +++ b/WebCore/bindings/scripts/CodeGeneratorCOM.pm @@ -900,7 +900,7 @@ sub GenerateCPPHeader "Forwarder" => $parentClassName }); push(@CPPHeaderContent, values(%attributes)); } - + # Add attribute names to attribute names set in case other ancestors # also define them. $attributeNameSet{$_->signature->name} = 1 foreach @attributeList; diff --git a/WebCore/bindings/scripts/CodeGeneratorJS.pm b/WebCore/bindings/scripts/CodeGeneratorJS.pm index 08ef971..4563018 100644 --- a/WebCore/bindings/scripts/CodeGeneratorJS.pm +++ b/WebCore/bindings/scripts/CodeGeneratorJS.pm @@ -145,7 +145,7 @@ sub UsesManualToJSImplementation { my $type = shift; - return 1 if $type eq "Node" or $type eq "Document" or $type eq "HTMLCollection" or $type eq "SVGPathSeg" or $type eq "StyleSheet" or $type eq "CSSRule" or $type eq "CSSValue" or $type eq "Event" or $type eq "ImageData" or $type eq "Element" or $type eq "Text"; + return 1 if $type eq "Node" or $type eq "Document" or $type eq "HTMLCollection" or $type eq "SVGPathSeg" or $type eq "StyleSheet" or $type eq "CSSRule" or $type eq "CSSValue" or $type eq "Event" or $type eq "ImageData" or $type eq "Element" or $type eq "Text" or $type eq "SVGElementInstance"; return 0; } @@ -279,7 +279,7 @@ sub GenerateGetOwnPropertySlotBody my @getOwnPropertySlotImpl = (); if ($interfaceName eq "NamedNodeMap" or $interfaceName eq "HTMLCollection") { - push(@getOwnPropertySlotImpl, " ${namespaceMaybe}JSValuePtr proto = prototype();\n"); + push(@getOwnPropertySlotImpl, " ${namespaceMaybe}JSValue proto = prototype();\n"); push(@getOwnPropertySlotImpl, " if (proto.isObject() && static_cast<${namespaceMaybe}JSObject*>(asObject(proto))->hasProperty(exec, propertyName))\n"); push(@getOwnPropertySlotImpl, " return false;\n\n"); } @@ -434,10 +434,10 @@ sub GenerateHeader } # Destructor - push(@headerContent, " virtual ~$className();\n") if (!$hasParent or $interfaceName eq "Document"); + push(@headerContent, " virtual ~$className();\n") if (!$hasParent or $interfaceName eq "Document" or $interfaceName eq "DOMWindow"); # Prototype - push(@headerContent, " static JSC::JSObject* createPrototype(JSC::ExecState*);\n") unless ($dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"}); + push(@headerContent, " static JSC::JSObject* createPrototype(JSC::ExecState*, JSC::JSGlobalObject*);\n") unless ($dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"}); $implIncludes{"${className}Custom.h"} = 1 if $dataNode->extendedAttributes->{"CustomHeader"} || $dataNode->extendedAttributes->{"CustomPutFunction"}; @@ -470,9 +470,9 @@ sub GenerateHeader # Getters if ($hasSetter) { - push(@headerContent, " virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValuePtr, JSC::PutPropertySlot&);\n"); - push(@headerContent, " virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValuePtr);\n") if $dataNode->extendedAttributes->{"HasCustomIndexSetter"}; - push(@headerContent, " bool customPut(JSC::ExecState*, const JSC::Identifier&, JSC::JSValuePtr, JSC::PutPropertySlot&);\n") if $dataNode->extendedAttributes->{"CustomPutFunction"}; + push(@headerContent, " virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);\n"); + push(@headerContent, " virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValue);\n") if $dataNode->extendedAttributes->{"HasCustomIndexSetter"}; + push(@headerContent, " bool customPut(JSC::ExecState*, const JSC::Identifier&, JSC::JSValue, JSC::PutPropertySlot&);\n") if $dataNode->extendedAttributes->{"CustomPutFunction"}; } # Class info @@ -482,13 +482,13 @@ sub GenerateHeader # Structure ID if ($interfaceName eq "DOMWindow") { push(@headerContent, - " static PassRefPtr<JSC::Structure> createStructure(JSC::JSValuePtr prototype)\n" . + " static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype)\n" . " {\n" . " return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, JSC::ImplementsHasInstance | JSC::NeedsThisConversion));\n" . " }\n\n"); } elsif ($hasGetter) { push(@headerContent, - " static PassRefPtr<JSC::Structure> createStructure(JSC::JSValuePtr prototype)\n" . + " static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype)\n" . " {\n" . " return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType));\n" . " }\n\n"); @@ -520,13 +520,13 @@ sub GenerateHeader push(@headerContent, " virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction);\n") if $dataNode->extendedAttributes->{"CustomDefineSetter"}; # Custom lookupGetter function - push(@headerContent, " virtual JSC::JSValuePtr lookupGetter(JSC::ExecState*, const JSC::Identifier& propertyName);\n") if $dataNode->extendedAttributes->{"CustomLookupGetter"}; + push(@headerContent, " virtual JSC::JSValue lookupGetter(JSC::ExecState*, const JSC::Identifier& propertyName);\n") if $dataNode->extendedAttributes->{"CustomLookupGetter"}; # Custom lookupSetter function - push(@headerContent, " virtual JSC::JSValuePtr lookupSetter(JSC::ExecState*, const JSC::Identifier& propertyName);\n") if $dataNode->extendedAttributes->{"CustomLookupSetter"}; + push(@headerContent, " virtual JSC::JSValue lookupSetter(JSC::ExecState*, const JSC::Identifier& propertyName);\n") if $dataNode->extendedAttributes->{"CustomLookupSetter"}; # Constructor object getter - push(@headerContent, " static JSC::JSValuePtr getConstructor(JSC::ExecState*);\n") if $dataNode->extendedAttributes->{"GenerateConstructor"}; + push(@headerContent, " static JSC::JSValue getConstructor(JSC::ExecState*);\n") if $dataNode->extendedAttributes->{"GenerateConstructor"}; my $numCustomFunctions = 0; my $numCustomAttributes = 0; @@ -536,8 +536,8 @@ sub GenerateHeader foreach (@{$dataNode->attributes}) { my $attribute = $_; $numCustomAttributes++ if $attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCCustom"}; - $numCustomAttributes++ if $attribute->signature->extendedAttributes->{"CustomGetter"}; - $numCustomAttributes++ if $attribute->signature->extendedAttributes->{"CustomSetter"}; + $numCustomAttributes++ if $attribute->signature->extendedAttributes->{"CustomGetter"} || $attribute->signature->extendedAttributes->{"JSCCustomGetter"}; + $numCustomAttributes++ if $attribute->signature->extendedAttributes->{"CustomSetter"} || $attribute->signature->extendedAttributes->{"JSCCustomSetter"}; } } @@ -546,15 +546,15 @@ sub GenerateHeader foreach my $attribute (@{$dataNode->attributes}) { if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCCustom"}) { - push(@headerContent, " JSC::JSValuePtr " . $codeGenerator->WK_lcfirst($attribute->signature->name) . "(JSC::ExecState*) const;\n"); + push(@headerContent, " JSC::JSValue " . $codeGenerator->WK_lcfirst($attribute->signature->name) . "(JSC::ExecState*) const;\n"); if ($attribute->type !~ /^readonly/) { - push(@headerContent, " void set" . $codeGenerator->WK_ucfirst($attribute->signature->name) . "(JSC::ExecState*, JSC::JSValuePtr);\n"); + push(@headerContent, " void set" . $codeGenerator->WK_ucfirst($attribute->signature->name) . "(JSC::ExecState*, JSC::JSValue);\n"); } - } elsif ($attribute->signature->extendedAttributes->{"CustomGetter"}) { - push(@headerContent, " JSC::JSValuePtr " . $codeGenerator->WK_lcfirst($attribute->signature->name) . "(JSC::ExecState*) const;\n"); - } elsif ($attribute->signature->extendedAttributes->{"CustomSetter"}) { + } elsif ($attribute->signature->extendedAttributes->{"CustomGetter"} || $attribute->signature->extendedAttributes->{"JSCCustomGetter"}) { + push(@headerContent, " JSC::JSValue " . $codeGenerator->WK_lcfirst($attribute->signature->name) . "(JSC::ExecState*) const;\n"); + } elsif ($attribute->signature->extendedAttributes->{"CustomSetter"} || $attribute->signature->extendedAttributes->{"JSCCustomSetter"}) { if ($attribute->type !~ /^readonly/) { - push(@headerContent, " void set" . $codeGenerator->WK_ucfirst($attribute->signature->name) . "(JSC::ExecState*, JSC::JSValuePtr);\n"); + push(@headerContent, " void set" . $codeGenerator->WK_ucfirst($attribute->signature->name) . "(JSC::ExecState*, JSC::JSValue);\n"); } } } @@ -569,7 +569,7 @@ sub GenerateHeader foreach my $function (@{$dataNode->functions}) { if ($function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"JSCCustom"}) { my $functionImplementationName = $function->signature->extendedAttributes->{"ImplementationFunction"} || $codeGenerator->WK_lcfirst($function->signature->name); - push(@headerContent, " JSC::JSValuePtr " . $functionImplementationName . "(JSC::ExecState*, const JSC::ArgList&);\n"); + push(@headerContent, " JSC::JSValue " . $functionImplementationName . "(JSC::ExecState*, const JSC::ArgList&);\n"); } } } @@ -601,21 +601,21 @@ sub GenerateHeader # Index getter if ($dataNode->extendedAttributes->{"HasIndexGetter"}) { - push(@headerContent, " static JSC::JSValuePtr indexGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n"); + push(@headerContent, " static JSC::JSValue indexGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n"); } if ($dataNode->extendedAttributes->{"HasCustomIndexGetter"}) { - push(@headerContent, " JSC::JSValuePtr getByIndex(JSC::ExecState*, unsigned index);\n"); + push(@headerContent, " JSC::JSValue getByIndex(JSC::ExecState*, unsigned index);\n"); } # Index setter if ($dataNode->extendedAttributes->{"HasCustomIndexSetter"}) { - push(@headerContent, " void indexSetter(JSC::ExecState*, unsigned index, JSC::JSValuePtr);\n"); + push(@headerContent, " void indexSetter(JSC::ExecState*, unsigned index, JSC::JSValue);\n"); } # Name getter if ($dataNode->extendedAttributes->{"HasNameGetter"} || $dataNode->extendedAttributes->{"HasOverridingNameGetter"}) { push(@headerContent, "private:\n"); push(@headerContent, " static bool canGetItemsForName(JSC::ExecState*, $implClassName*, const JSC::Identifier&);\n"); - push(@headerContent, " static JSC::JSValuePtr nameGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n"); + push(@headerContent, " static JSC::JSValue nameGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n"); } push(@headerContent, "};\n\n"); @@ -629,48 +629,59 @@ sub GenerateHeader if (!$hasParent || $dataNode->extendedAttributes->{"GenerateToJS"}) { if ($podType) { - push(@headerContent, "JSC::JSValuePtr toJS(JSC::ExecState*, JSSVGPODTypeWrapper<$podType>*, SVGElement* context);\n"); + push(@headerContent, "JSC::JSValue toJS(JSC::ExecState*, JSSVGPODTypeWrapper<$podType>*, SVGElement* context);\n"); } elsif (IsSVGTypeNeedingContextParameter($implClassName)) { - push(@headerContent, "JSC::JSValuePtr toJS(JSC::ExecState*, $implType*, SVGElement* context);\n"); + push(@headerContent, "JSC::JSValue toJS(JSC::ExecState*, $implType*, SVGElement* context);\n"); } else { - push(@headerContent, "JSC::JSValuePtr toJS(JSC::ExecState*, $implType*);\n"); + push(@headerContent, "JSC::JSValue toJS(JSC::ExecState*, $implType*);\n"); } } if (!$hasParent || $dataNode->extendedAttributes->{"GenerateNativeConverter"}) { if ($podType) { - push(@headerContent, "$podType to${interfaceName}(JSC::JSValuePtr);\n"); + push(@headerContent, "$podType to${interfaceName}(JSC::JSValue);\n"); } elsif ($interfaceName eq "NodeFilter") { - push(@headerContent, "PassRefPtr<NodeFilter> toNodeFilter(JSC::JSValuePtr);\n"); + push(@headerContent, "PassRefPtr<NodeFilter> toNodeFilter(JSC::JSValue);\n"); } else { - push(@headerContent, "$implClassName* to${interfaceName}(JSC::JSValuePtr);\n"); + push(@headerContent, "$implClassName* to${interfaceName}(JSC::JSValue);\n"); } } if ($interfaceName eq "Node" or $interfaceName eq "Element" or $interfaceName eq "Text" or $interfaceName eq "CDATASection") { - push(@headerContent, "JSC::JSValuePtr toJSNewlyCreated(JSC::ExecState*, $interfaceName*);\n"); + push(@headerContent, "JSC::JSValue toJSNewlyCreated(JSC::ExecState*, $interfaceName*);\n"); } push(@headerContent, "\n"); # Add prototype declaration. push(@headerContent, "class ${className}Prototype : public JSC::JSObject {\n"); + push(@headerContent, " typedef JSC::JSObject Base;\n"); push(@headerContent, "public:\n"); if ($interfaceName eq "DOMWindow") { push(@headerContent, " void* operator new(size_t);\n"); } elsif ($interfaceName eq "WorkerContext") { push(@headerContent, " void* operator new(size_t, JSC::JSGlobalData*);\n"); } else { - push(@headerContent, " static JSC::JSObject* self(JSC::ExecState*);\n"); + push(@headerContent, " static JSC::JSObject* self(JSC::ExecState*, JSC::JSGlobalObject*);\n"); } push(@headerContent, " virtual const JSC::ClassInfo* classInfo() const { return &s_info; }\n"); push(@headerContent, " static const JSC::ClassInfo s_info;\n"); - if ($numFunctions > 0 || $numConstants > 0) { + if ($numFunctions > 0 || $numConstants > 0 || $dataNode->extendedAttributes->{"CustomPrototypeGetOwnPropertySlot"}) { push(@headerContent, " virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&);\n"); + push(@headerContent, " bool customGetOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&);\n") if $dataNode->extendedAttributes->{"CustomPrototypeGetOwnPropertySlot"}; + push(@headerContent, - " static PassRefPtr<JSC::Structure> createStructure(JSC::JSValuePtr prototype)\n" . + " static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype)\n" . " {\n" . " return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType));\n" . " }\n"); } + if ($dataNode->extendedAttributes->{"CustomPrototypePutFunction"}) { + push(@headerContent, " virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);\n"); + push(@headerContent, " bool customPut(JSC::ExecState*, const JSC::Identifier&, JSC::JSValue, JSC::PutPropertySlot&);\n"); + } + + # Custom defineGetter function + push(@headerContent, " virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction);\n") if $dataNode->extendedAttributes->{"CustomPrototypeDefineGetter"}; + push(@headerContent, " ${className}Prototype(PassRefPtr<JSC::Structure> structure) : JSC::JSObject(structure) { }\n"); push(@headerContent, "};\n\n"); @@ -679,7 +690,7 @@ sub GenerateHeader push(@headerContent,"// Functions\n\n"); foreach my $function (@{$dataNode->functions}) { my $functionName = $codeGenerator->WK_lcfirst($className) . "PrototypeFunction" . $codeGenerator->WK_ucfirst($function->signature->name); - push(@headerContent, "JSC::JSValuePtr ${functionName}(JSC::ExecState*, JSC::JSObject*, JSC::JSValuePtr, const JSC::ArgList&);\n"); + push(@headerContent, "JSC::JSValue JSC_HOST_CALL ${functionName}(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&);\n"); } } @@ -687,16 +698,16 @@ sub GenerateHeader push(@headerContent,"// Attributes\n\n"); foreach my $attribute (@{$dataNode->attributes}) { my $getter = "js" . $interfaceName . $codeGenerator->WK_ucfirst($attribute->signature->name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : ""); - push(@headerContent, "JSC::JSValuePtr ${getter}(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n"); + push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n"); unless ($attribute->type =~ /readonly/) { my $setter = "setJS" . $interfaceName . $codeGenerator->WK_ucfirst($attribute->signature->name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : ""); - push(@headerContent, "void ${setter}(JSC::ExecState*, JSC::JSObject*, JSC::JSValuePtr);\n"); + push(@headerContent, "void ${setter}(JSC::ExecState*, JSC::JSObject*, JSC::JSValue);\n"); } } if ($dataNode->extendedAttributes->{"GenerateConstructor"}) { my $getter = "js" . $interfaceName . "Constructor"; - push(@headerContent, "JSC::JSValuePtr ${getter}(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n"); + push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n"); } } @@ -704,7 +715,7 @@ sub GenerateHeader push(@headerContent,"// Constants\n\n"); foreach my $constant (@{$dataNode->constants}) { my $getter = "js" . $interfaceName . $codeGenerator->WK_ucfirst($constant->name); - push(@headerContent, "JSC::JSValuePtr ${getter}(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n"); + push(@headerContent, "JSC::JSValue ${getter}(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);\n"); } } @@ -771,6 +782,7 @@ sub GenerateImplementation my @hashSpecials = (); my @hashValue1 = (); my @hashValue2 = (); + my %conditionals = (); my @entries = (); @@ -794,6 +806,11 @@ sub GenerateImplementation my $setter = "setJS" . $interfaceName . $codeGenerator->WK_ucfirst($attribute->signature->name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : ""); push(@hashValue2, $setter); } + + my $conditional = $attribute->signature->extendedAttributes->{"Conditional"}; + if ($conditional) { + $conditionals{$name} = $conditional; + } } if ($dataNode->extendedAttributes->{"GenerateConstructor"}) { @@ -806,7 +823,8 @@ sub GenerateImplementation $object->GenerateHashTable($hashName, $hashSize, \@hashKeys, \@hashSpecials, - \@hashValue1, \@hashValue2); + \@hashValue1, \@hashValue2, + \%conditionals); } my $numConstants = @{$dataNode->constants}; @@ -872,7 +890,7 @@ sub GenerateImplementation my @specials = (); push(@specials, "DontDelete") unless $function->signature->extendedAttributes->{"Deletable"}; push(@specials, "DontEnum") if $function->signature->extendedAttributes->{"DontEnum"}; - push(@specials, "Function"); + push(@specials, "Function"); my $special = (@specials > 0) ? join("|", @specials) : "0"; push(@hashSpecials, $special); } @@ -901,15 +919,23 @@ sub GenerateImplementation push(@implContent, " return globalData->heap.allocate(size);\n"); push(@implContent, "}\n\n"); } else { - push(@implContent, "JSObject* ${className}Prototype::self(ExecState* exec)\n"); + push(@implContent, "JSObject* ${className}Prototype::self(ExecState* exec, JSGlobalObject* globalObject)\n"); push(@implContent, "{\n"); - push(@implContent, " return getDOMPrototype<${className}>(exec);\n"); + push(@implContent, " return getDOMPrototype<${className}>(exec, globalObject);\n"); push(@implContent, "}\n\n"); } - if ($numConstants > 0 || $numFunctions > 0) { + if ($numConstants > 0 || $numFunctions > 0 || $dataNode->extendedAttributes->{"CustomPrototypeGetOwnPropertySlot"}) { push(@implContent, "bool ${className}Prototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)\n"); push(@implContent, "{\n"); - if ($numConstants eq 0) { + + if ($dataNode->extendedAttributes->{"CustomPrototypeGetOwnPropertySlot"}) { + push(@implContent, " if (customGetOwnPropertySlot(exec, propertyName, slot))\n"); + push(@implContent, " return true;\n"); + } + + if ($numConstants eq 0 && $numFunctions eq 0) { + push(@implContent, " return Base::getOwnPropertySlot(exec, propertyName, slot);\n"); + } elsif ($numConstants eq 0) { push(@implContent, " return getStaticFunctionSlot<JSObject>(exec, " . prototypeHashTableAccessor($dataNode->extendedAttributes->{"NoStaticTables"}, $className) . ", this, propertyName, slot);\n"); } elsif ($numFunctions eq 0) { push(@implContent, " return getStaticValueSlot<${className}Prototype, JSObject>(exec, " . prototypeHashTableAccessor($dataNode->extendedAttributes->{"NoStaticTables"}, $className) . ", this, propertyName, slot);\n"); @@ -919,6 +945,15 @@ sub GenerateImplementation push(@implContent, "}\n\n"); } + if ($dataNode->extendedAttributes->{"CustomPrototypePutFunction"}) { + push(@implContent, "void ${className}Prototype::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)\n"); + push(@implContent, "{\n"); + push(@implContent, " if (customPut(exec, propertyName, value, slot))\n"); + push(@implContent, " return;\n"); + push(@implContent, " Base::put(exec, propertyName, value, slot);\n"); + push(@implContent, "}\n\n"); + } + # - Initialize static ClassInfo object if ($numAttributes > 0 && $dataNode->extendedAttributes->{"NoStaticTables"}) { push(@implContent, "static const HashTable* get${className}Table(ExecState* exec)\n"); @@ -979,12 +1014,17 @@ sub GenerateImplementation push(@implContent, "}\n\n"); # Destructor - if (!$hasParent) { + if (!$hasParent || $interfaceName eq "DOMWindow") { push(@implContent, "${className}::~$className()\n"); push(@implContent, "{\n"); if ($interfaceName eq "Node") { - push(@implContent, " forgetDOMNode(m_impl->document(), m_impl.get());\n"); + $implIncludes{"RegisteredEventListener.h"} = 1; + push(@implContent, " invalidateEventListeners(m_impl->eventListeners());\n"); + push(@implContent, " forgetDOMNode(m_impl->document(), m_impl.get());\n"); + } elsif ($interfaceName eq "DOMWindow") { + $implIncludes{"RegisteredEventListener.h"} = 1; + push(@implContent, " invalidateEventListeners(impl()->eventListeners());\n"); } else { if ($podType) { my $animatedType = $implClassName; @@ -998,7 +1038,7 @@ sub GenerateImplementation push(@implContent, " forgetDOMObject(*Heap::heap(this)->globalData(), m_impl.get());\n"); } - push(@implContent, "\n}\n\n"); + push(@implContent, "}\n\n"); } # Document needs a special destructor because it's a special case for caching. It needs @@ -1009,12 +1049,12 @@ sub GenerateImplementation } if (!$dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"}) { - push(@implContent, "JSObject* ${className}::createPrototype(ExecState* exec)\n"); + push(@implContent, "JSObject* ${className}::createPrototype(ExecState* exec, JSGlobalObject* globalObject)\n"); push(@implContent, "{\n"); if ($hasParent && $parentClassName ne "JSC::DOMNodeFilter") { - push(@implContent, " return new (exec) ${className}Prototype(${className}Prototype::createStructure(${parentClassName}Prototype::self(exec)));\n"); + push(@implContent, " return new (exec) ${className}Prototype(${className}Prototype::createStructure(${parentClassName}Prototype::self(exec, globalObject)));\n"); } else { - push(@implContent, " return new (exec) ${className}Prototype(${className}Prototype::createStructure(exec->lexicalGlobalObject()->objectPrototype()));\n"); + push(@implContent, " return new (exec) ${className}Prototype(${className}Prototype::createStructure(globalObject->objectPrototype()));\n"); } push(@implContent, "}\n\n"); } @@ -1059,7 +1099,13 @@ sub GenerateImplementation my $getFunctionName = "js" . $interfaceName . $codeGenerator->WK_ucfirst($attribute->signature->name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : ""); my $implGetterFunctionName = $codeGenerator->WK_lcfirst($name); - push(@implContent, "JSValuePtr ${getFunctionName}(ExecState* exec, const Identifier&, const PropertySlot& slot)\n"); + my $conditional = $attribute->signature->extendedAttributes->{"Conditional"}; + if ($conditional) { + $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")"; + push(@implContent, "#if ${conditionalString}\n"); + } + + push(@implContent, "JSValue ${getFunctionName}(ExecState* exec, const Identifier&, const PropertySlot& slot)\n"); push(@implContent, "{\n"); my $implClassNameForValueConversion = ""; @@ -1074,7 +1120,7 @@ sub GenerateImplementation push(@implContent, " return jsUndefined();\n"); } - if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCCustom"} || $attribute->signature->extendedAttributes->{"CustomGetter"}) { + if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCCustom"} || $attribute->signature->extendedAttributes->{"CustomGetter"} || $attribute->signature->extendedAttributes->{"JSCCustomGetter"}) { push(@implContent, " return static_cast<$className*>(asObject(slot.slotBase()))->$implGetterFunctionName(exec);\n"); } elsif ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) { $implIncludes{"JSDOMBinding.h"} = 1; @@ -1090,8 +1136,8 @@ sub GenerateImplementation push(@implContent, " UNUSED_PARAM(exec);\n"); push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(asObject(slot.slotBase()))->impl());\n"); push(@implContent, " if (EventListener* listener = imp->$implGetterFunctionName()) {\n"); - push(@implContent, " if (JSObject* function = listener->function())\n"); - push(@implContent, " return function;\n"); + push(@implContent, " if (JSObject* jsFunction = listener->jsFunction())\n"); + push(@implContent, " return jsFunction;\n"); push(@implContent, " }\n"); push(@implContent, " return jsNull();\n"); } elsif ($attribute->signature->type =~ /Constructor$/) { @@ -1123,23 +1169,29 @@ sub GenerateImplementation if ($podType) { push(@implContent, " $podType imp(*static_cast<$className*>(asObject(slot.slotBase()))->impl());\n"); - push(@implContent, " JSC::JSValuePtr result = " . NativeToJSValue($attribute->signature, 0, $implClassName, "", "imp.$implGetterFunctionName(ec)", "static_cast<$className*>(asObject(slot.slotBase()))") . ";\n"); + push(@implContent, " JSC::JSValue result = " . NativeToJSValue($attribute->signature, 0, $implClassName, "", "imp.$implGetterFunctionName(ec)", "static_cast<$className*>(asObject(slot.slotBase()))") . ";\n"); } else { push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(asObject(slot.slotBase()))->impl());\n"); - push(@implContent, " JSC::JSValuePtr result = " . NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, "imp->$implGetterFunctionName(ec)", "static_cast<$className*>(asObject(slot.slotBase()))") . ";\n"); + push(@implContent, " JSC::JSValue result = " . NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, "imp->$implGetterFunctionName(ec)", "static_cast<$className*>(asObject(slot.slotBase()))") . ";\n"); } push(@implContent, " setDOMException(exec, ec);\n"); push(@implContent, " return result;\n"); } - push(@implContent, "}\n\n"); + push(@implContent, "}\n"); + + if ($conditional) { + push(@implContent, "#endif\n"); + } + + push(@implContent, "\n"); } if ($dataNode->extendedAttributes->{"GenerateConstructor"}) { my $constructorFunctionName = "js" . $interfaceName . "Constructor"; - push(@implContent, "JSValuePtr ${constructorFunctionName}(ExecState* exec, const Identifier&, const PropertySlot& slot)\n"); + push(@implContent, "JSValue ${constructorFunctionName}(ExecState* exec, const Identifier&, const PropertySlot& slot)\n"); push(@implContent, "{\n"); push(@implContent, " return static_cast<$className*>(asObject(slot.slotBase()))->getConstructor(exec);\n"); push(@implContent, "}\n"); @@ -1157,7 +1209,7 @@ sub GenerateImplementation || $dataNode->extendedAttributes->{"HasCustomIndexSetter"}; if ($hasSetter) { - push(@implContent, "void ${className}::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)\n"); + push(@implContent, "void ${className}::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)\n"); push(@implContent, "{\n"); if ($dataNode->extendedAttributes->{"HasCustomIndexSetter"}) { push(@implContent, " bool ok;\n"); @@ -1180,7 +1232,7 @@ sub GenerateImplementation push(@implContent, "}\n\n"); if ($dataNode->extendedAttributes->{"HasCustomIndexSetter"}) { - push(@implContent, "void ${className}::put(ExecState* exec, unsigned propertyName, JSValuePtr value)\n"); + push(@implContent, "void ${className}::put(ExecState* exec, unsigned propertyName, JSValue value)\n"); push(@implContent, "{\n"); push(@implContent, " indexSetter(exec, propertyName, value);\n"); push(@implContent, " return;\n"); @@ -1195,7 +1247,7 @@ sub GenerateImplementation my $putFunctionName = "setJS" . $interfaceName . $codeGenerator->WK_ucfirst($name) . ($attribute->signature->type =~ /Constructor$/ ? "Constructor" : ""); my $implSetterFunctionName = $codeGenerator->WK_ucfirst($name); - push(@implContent, "void ${putFunctionName}(ExecState* exec, JSObject* thisObject, JSValuePtr value)\n"); + push(@implContent, "void ${putFunctionName}(ExecState* exec, JSObject* thisObject, JSValue value)\n"); push(@implContent, "{\n"); if ($dataNode->extendedAttributes->{"CheckDomainSecurity"} && !$attribute->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) { @@ -1207,17 +1259,12 @@ sub GenerateImplementation push(@implContent, " return;\n"); } - if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCCustom"} || $attribute->signature->extendedAttributes->{"CustomSetter"}) { + if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCCustom"} || $attribute->signature->extendedAttributes->{"CustomSetter"} || $attribute->signature->extendedAttributes->{"JSCCustomSetter"}) { push(@implContent, " static_cast<$className*>(thisObject)->set$implSetterFunctionName(exec, value);\n"); } elsif ($type eq "EventListener") { $implIncludes{"JSEventListener.h"} = 1; + push(@implContent, " UNUSED_PARAM(exec);\n"); push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(thisObject)->impl());\n"); - my $listenerType; - if ($attribute->signature->extendedAttributes->{"ProtectedListener"}) { - $listenerType = "JSProtectedEventListener"; - } else { - $listenerType = "JSEventListener"; - } if ($dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"}) { push(@implContent, " JSDOMGlobalObject* globalObject = static_cast<$className*>(thisObject);\n"); } else { @@ -1227,7 +1274,7 @@ sub GenerateImplementation push(@implContent, " if (!globalObject)\n"); push(@implContent, " return;\n"); } - push(@implContent, " imp->set$implSetterFunctionName(globalObject->findOrCreate${listenerType}(exec, value, true));\n"); + push(@implContent, " imp->set$implSetterFunctionName(globalObject->createJSAttributeEventListener(value));\n"); } elsif ($attribute->signature->type =~ /Constructor$/) { my $constructorType = $attribute->signature->type; $constructorType =~ s/Constructor$//; @@ -1284,7 +1331,7 @@ sub GenerateImplementation } if ($dataNode->extendedAttributes->{"GenerateConstructor"}) { - push(@implContent, "JSValuePtr ${className}::getConstructor(ExecState* exec)\n{\n"); + push(@implContent, "JSValue ${className}::getConstructor(ExecState* exec)\n{\n"); push(@implContent, " return getDOMConstructor<${className}Constructor>(exec);\n"); push(@implContent, "}\n\n"); } @@ -1297,14 +1344,14 @@ sub GenerateImplementation my $functionName = $codeGenerator->WK_lcfirst($className) . "PrototypeFunction" . $codeGenerator->WK_ucfirst($function->signature->name); my $functionImplementationName = $function->signature->extendedAttributes->{"ImplementationFunction"} || $codeGenerator->WK_lcfirst($function->signature->name); - push(@implContent, "JSValuePtr ${functionName}(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)\n"); + push(@implContent, "JSValue JSC_HOST_CALL ${functionName}(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)\n"); push(@implContent, "{\n"); push(@implContent, " UNUSED_PARAM(args);\n"); $implKJSInclude{"Error.h"} = 1; if ($interfaceName eq "DOMWindow") { - push(@implContent, " $className* castedThisObj = toJSDOMWindow(thisValue);\n"); + push(@implContent, " $className* castedThisObj = toJSDOMWindow(thisValue.toThisObject(exec));\n"); push(@implContent, " if (!castedThisObj)\n"); push(@implContent, " return throwError(exec, TypeError);\n"); } else { @@ -1372,15 +1419,15 @@ sub GenerateImplementation if ($parameter->type eq "XPathNSResolver") { push(@implContent, " RefPtr<XPathNSResolver> customResolver;\n"); - push(@implContent, " XPathNSResolver* resolver = toXPathNSResolver(args.at(exec, $paramIndex));\n"); + push(@implContent, " XPathNSResolver* resolver = toXPathNSResolver(args.at($paramIndex));\n"); push(@implContent, " if (!resolver) {\n"); - push(@implContent, " customResolver = JSCustomXPathNSResolver::create(exec, args.at(exec, $paramIndex));\n"); + push(@implContent, " customResolver = JSCustomXPathNSResolver::create(exec, args.at($paramIndex));\n"); push(@implContent, " if (exec->hadException())\n"); push(@implContent, " return jsUndefined();\n"); push(@implContent, " resolver = customResolver.get();\n"); push(@implContent, " }\n"); } else { - push(@implContent, " " . GetNativeTypeFromSignature($parameter) . " $name = " . JSValueToNative($parameter, "args.at(exec, $paramIndex)") . ";\n"); + push(@implContent, " " . GetNativeTypeFromSignature($parameter) . " $name = " . JSValueToNative($parameter, "args.at($paramIndex)") . ";\n"); # If a parameter is "an index" and it's negative it should throw an INDEX_SIZE_ERR exception. # But this needs to be done in the bindings, because the type is unsigned and the fact that it @@ -1419,7 +1466,7 @@ sub GenerateImplementation my $getter = "js" . $interfaceName . $codeGenerator->WK_ucfirst($constant->name); # FIXME: this casts into int to match our previous behavior which turned 0xFFFFFFFF in -1 for NodeFilter.SHOW_ALL - push(@implContent, "JSValuePtr ${getter}(ExecState* exec, const Identifier&, const PropertySlot&)\n"); + push(@implContent, "JSValue ${getter}(ExecState* exec, const Identifier&, const PropertySlot&)\n"); push(@implContent, "{\n"); push(@implContent, " return jsNumber(exec, static_cast<int>(" . $constant->value . "));\n"); push(@implContent, "}\n\n"); @@ -1427,7 +1474,7 @@ sub GenerateImplementation } if ($dataNode->extendedAttributes->{"HasIndexGetter"}) { - push(@implContent, "\nJSValuePtr ${className}::indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)\n"); + push(@implContent, "\nJSValue ${className}::indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)\n"); push(@implContent, "{\n"); push(@implContent, " ${className}* thisObj = static_cast<$className*>(asObject(slot.slotBase()));\n"); if (IndexGetterReturnsStrings($implClassName)) { @@ -1445,11 +1492,11 @@ sub GenerateImplementation if ((!$hasParent or $dataNode->extendedAttributes->{"GenerateToJS"}) and !UsesManualToJSImplementation($implClassName)) { if ($podType) { - push(@implContent, "JSC::JSValuePtr toJS(JSC::ExecState* exec, JSSVGPODTypeWrapper<$podType>* object, SVGElement* context)\n"); + push(@implContent, "JSC::JSValue toJS(JSC::ExecState* exec, JSSVGPODTypeWrapper<$podType>* object, SVGElement* context)\n"); } elsif (IsSVGTypeNeedingContextParameter($implClassName)) { - push(@implContent, "JSC::JSValuePtr toJS(JSC::ExecState* exec, $implType* object, SVGElement* context)\n"); + push(@implContent, "JSC::JSValue toJS(JSC::ExecState* exec, $implType* object, SVGElement* context)\n"); } else { - push(@implContent, "JSC::JSValuePtr toJS(JSC::ExecState* exec, $implType* object)\n"); + push(@implContent, "JSC::JSValue toJS(JSC::ExecState* exec, $implType* object)\n"); } push(@implContent, "{\n"); @@ -1465,9 +1512,9 @@ sub GenerateImplementation if ((!$hasParent or $dataNode->extendedAttributes->{"GenerateNativeConverter"}) and !$dataNode->extendedAttributes->{"CustomNativeConverter"}) { if ($podType) { - push(@implContent, "$podType to${interfaceName}(JSC::JSValuePtr value)\n"); + push(@implContent, "$podType to${interfaceName}(JSC::JSValue value)\n"); } else { - push(@implContent, "$implClassName* to${interfaceName}(JSC::JSValuePtr value)\n"); + push(@implContent, "$implClassName* to${interfaceName}(JSC::JSValue value)\n"); } push(@implContent, "{\n"); @@ -1516,7 +1563,7 @@ sub GenerateImplementationFunctionCall() push(@implContent, $indent . "return jsUndefined();\n"); } else { - push(@implContent, "\n" . $indent . "JSC::JSValuePtr result = " . NativeToJSValue($function->signature, 1, $implClassName, "", $functionString, "castedThisObj") . ";\n"); + push(@implContent, "\n" . $indent . "JSC::JSValue result = " . NativeToJSValue($function->signature, 1, $implClassName, "", $functionString, "castedThisObj") . ";\n"); push(@implContent, $indent . "setDOMException(exec, ec);\n") if @{$function->raisesExceptions}; if ($podType and not $function->signature->extendedAttributes->{"Immutable"}) { @@ -1687,10 +1734,6 @@ sub NativeToJSValue $implIncludes{"CSSMutableStyleDeclaration.h"} = 1; } - if ($type eq "NamedNodeMap") { - $implIncludes{"NamedAttrMap.h"} = 1; - } - if ($type eq "NodeList") { $implIncludes{"NameNodeList.h"} = 1; } @@ -1748,6 +1791,7 @@ sub GenerateHashTable my $specials = shift; my $value1 = shift; my $value2 = shift; + my $conditionals = shift; # Generate size data for two hash tables # - The 'perfect' size makes a table large enough for perfect hashing @@ -1832,7 +1876,19 @@ tableSizeLoop: push(@implContent, "\nstatic const HashTableValue $nameEntries\[$count\] =\n\{\n"); $i = 0; foreach my $key (@{$keys}) { + my $conditional; + + if ($conditionals) { + $conditional = $conditionals->{$key}; + } + if ($conditional) { + my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")"; + push(@implContent, "#if ${conditionalString}\n"); + } push(@implContent, " { \"$key\", @$specials[$i], (intptr_t)@$value1[$i], (intptr_t)@$value2[$i] },\n"); + if ($conditional) { + push(@implContent, "#endif\n"); + } ++$i; } push(@implContent, " { 0, 0, 0, 0 }\n"); @@ -1963,13 +2019,13 @@ public: ${className}Constructor(ExecState* exec) : DOMObject(${className}Constructor::createStructure(exec->lexicalGlobalObject()->objectPrototype())) { - putDirect(exec->propertyNames().prototype, ${protoClassName}::self(exec), None); + putDirect(exec->propertyNames().prototype, ${protoClassName}::self(exec, exec->lexicalGlobalObject()), None); } virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); virtual const ClassInfo* classInfo() const { return &s_info; } static const ClassInfo s_info; - static PassRefPtr<Structure> createStructure(JSValuePtr proto) + static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance)); } diff --git a/WebCore/bindings/scripts/CodeGeneratorObjC.pm b/WebCore/bindings/scripts/CodeGeneratorObjC.pm index 5ec960e..fc265f9 100644 --- a/WebCore/bindings/scripts/CodeGeneratorObjC.pm +++ b/WebCore/bindings/scripts/CodeGeneratorObjC.pm @@ -3,7 +3,7 @@ # Copyright (C) 2006 Anders Carlsson <andersca@mac.com> # Copyright (C) 2006, 2007 Samuel Weinig <sam@webkit.org> # Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org> -# Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. +# Copyright (C) 2006, 2007, 2008, 2009 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 @@ -33,7 +33,6 @@ my $newPublicClass = 0; my $interfaceAvailabilityVersion = ""; my $isProtocol = 0; my $noImpl = 0; -my @ivars = (); my @headerContentHeader = (); my @headerContent = (); @@ -130,10 +129,10 @@ my %conflictMethod = ( my $fatalError = 0; -# Default Licence Templates -my $headerLicenceTemplate = << "EOF"; +# Default License Templates +my $headerLicenseTemplate = << "EOF"; /* - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2006 Samuel Weinig <sam.weinig\@gmail.com> * * Redistribution and use in source and binary forms, with or without @@ -159,7 +158,7 @@ my $headerLicenceTemplate = << "EOF"; */ EOF -my $implementationLicenceTemplate = << "EOF"; +my $implementationLicenseTemplate = << "EOF"; /* * This file is part of the WebKit open source project. * This file has been generated by generate-bindings.pl. DO NOT MODIFY! @@ -218,7 +217,7 @@ sub ReadPublicInterfaces my $fileName = "WebCore/bindings/objc/PublicDOMInterfaces.h"; open FILE, "-|", "/usr/bin/gcc", "-E", "-P", "-x", "objective-c", - (map { "-D$_" } split(/ /, $defines)), "-DOBJC_CODE_GENERATION", $fileName or die "Could not open $fileName"; + (map { "-D$_" } split(/ +/, $defines)), "-DOBJC_CODE_GENERATION", $fileName or die "Could not open $fileName"; my @documentContent = <FILE>; close FILE; @@ -455,47 +454,24 @@ sub GetPropertyAttributes push(@attributes, "readonly") if $readOnly; -# FIXME: uncomment these lines once <rdar://problem/4996504> is fixed. -# unless ($readOnly) { - if ($codeGenerator->IsStringType($type) || IsNativeObjCType($type)) { - push(@attributes, "copy"); - } elsif ($codeGenerator->IsPodType($type) || $codeGenerator->IsSVGAnimatedType($type)) { - push(@attributes, "retain"); - } elsif (!$codeGenerator->IsStringType($type) && !$codeGenerator->IsPrimitiveType($type) && $type ne "DOMTimeStamp" && $type ne "CompareHow" && $type ne "SVGPaintType") { - push(@attributes, "retain"); - } -# } + # FIXME: <rdar://problem/5049934> Consider using 'nonatomic' on the DOM @property declarations. + if ($codeGenerator->IsStringType($type) || IsNativeObjCType($type)) { + push(@attributes, "copy"); + } elsif ($codeGenerator->IsPodType($type) || $codeGenerator->IsSVGAnimatedType($type)) { + push(@attributes, "retain"); + } elsif (!$codeGenerator->IsStringType($type) && !$codeGenerator->IsPrimitiveType($type) && $type ne "DOMTimeStamp" && $type ne "CompareHow" && $type ne "SVGPaintType") { + push(@attributes, "retain"); + } return "" unless @attributes > 0; return "(" . join(", ", @attributes) . ")"; } -sub GetObjCTypeMaker +sub ConversionNeeded { my $type = $codeGenerator->StripModule(shift); - return "" if $codeGenerator->IsNonPointerType($type) or $codeGenerator->IsStringType($type) or IsNativeObjCType($type); - return "_wrapAbstractView" if $type eq "DOMWindow"; - return "_wrap$type"; -} - -sub GetObjCTypeGetterName -{ - my $type = $codeGenerator->StripModule(shift); - - my $typeGetter = ""; - if ($type =~ /^(HTML|CSS|SVG)/ or $type eq "DOMImplementation" or $type eq "CDATASection" or $type eq "RGBColor") { - $typeGetter = $type; - } elsif ($type =~ /^XPath(.+)/) { - $typeGetter = "xpath" . $1; - } elsif ($type eq "DOMWindow") { - $typeGetter = "abstractView"; - } else { - $typeGetter = lcfirst($type); - } - - # put into the form "_fooBar" for type FooBar. - return "_" . $typeGetter; + return !$codeGenerator->IsNonPointerType($type) && !$codeGenerator->IsStringType($type) && !IsNativeObjCType($type); } sub GetObjCTypeGetter @@ -507,65 +483,10 @@ sub GetObjCTypeGetter return $argName . "Node" if $type eq "EventTarget"; return "static_cast<WebCore::Range::CompareHow>($argName)" if $type eq "CompareHow"; return "static_cast<WebCore::SVGPaint::SVGPaintType>($argName)" if $type eq "SVGPaintType"; - - my $typeGetterMethodName = GetObjCTypeGetterName($type); - return "WTF::getPtr(nativeEventListener)" if $type eq "EventListener"; return "WTF::getPtr(nativeNodeFilter)" if $type eq "NodeFilter"; return "WTF::getPtr(nativeResolver)" if $type eq "XPathNSResolver"; - return "[$argName $typeGetterMethodName]"; -} - -sub GetInternalTypeGetterSignature -{ - my ($interfaceName, $podType) = @_; - - my $implClassNameWithNamespace = "WebCore::" . GetImplClassName($interfaceName); - my $podTypeWithNamespace; - if ($podType) { - $podTypeWithNamespace = ($podType eq "float") ? "$podType" : "WebCore::$podType"; - } - - # - Type-Getter - # - (WebCore::FooBar *)_fooBar for implementation class FooBar - my $typeGetterName = GetObjCTypeGetterName($interfaceName); - return "- " . ($podType ? "($podTypeWithNamespace)" : "($implClassNameWithNamespace *)") . $typeGetterName; -} - -sub GetInternalTypeMakerSignature -{ - my ($interfaceName, $podType) = @_; - - my $className = GetClassName($interfaceName); - my $implClassNameWithNamespace = "WebCore::" . GetImplClassName($interfaceName); - my $podTypeWithNamespace; - if ($podType) { - $podTypeWithNamespace = ($podType eq "float") ? "$podType" : "WebCore::$podType"; - } - - my @ivarsToRetain = (); - my $ivarsToInit = ""; - my $typeMakerSigAddition = ""; - if (@ivars > 0) { - my @ivarsInitSig = (); - my @ivarsInitCall = (); - foreach $attribute (@ivars) { - my $name = $attribute->signature->name; - my $memberName = "m_" . $name; - my $varName = "in" . $name; - my $type = GetObjCType($attribute->signature->type); - push(@ivarsInitSig, "$name:($type)$varName"); - push(@ivarsInitCall, "$name:$varName"); - push(@ivarsToRetain, " $memberName = [$varName retain];\n"); - } - $ivarsToInit = " " . join(" ", @ivarsInitCall); - $typeMakerSigAddition = " " . join(" ", @ivarsInitSig); - } - - my $typeMakerName = GetObjCTypeMaker($interfaceName); - return ("+ ($className *)$typeMakerName:(" . ($podType ? "$podTypeWithNamespace" : "$implClassNameWithNamespace *") . ")impl" . $typeMakerSigAddition, - $typeMakerSigAddition, - $ivarsToInit); + return "core($argName)"; } sub AddForwardDeclarationsForType @@ -602,77 +523,89 @@ sub AddIncludesForType } if ($type eq "RGBColor") { - $implIncludes{"Color.h"} = 1; - $implIncludes{"DOM$type.h"} = 1; + $implIncludes{"DOMRGBColorInternal.h"} = 1; return; } if ($type eq "DOMWindow") { - $implIncludes{"DOMAbstractView.h"} = 1; - $implIncludes{"$type.h"} = 1; + $implIncludes{"DOMAbstractViewInternal.h"} = 1; + $implIncludes{"DOMWindow.h"} = 1; return; } if ($type eq "DOMImplementation") { + $implIncludes{"DOMDOMImplementationInternal.h"} = 1; $implIncludes{"DOMImplementationFront.h"} = 1; - $implIncludes{"DOM$type.h"} = 1; return; } if ($type eq "EventTarget") { $implIncludes{"Node.h"} = 1; - $implIncludes{"DOM$type.h"} = 1; + $implIncludes{"DOMEventTarget.h"} = 1; return; } if ($codeGenerator->IsSVGAnimatedType($type)) { $implIncludes{"SVGAnimatedTemplate.h"} = 1; - $implIncludes{"DOM$type.h"} = 1; + $implIncludes{"DOM${type}Internal.h"} = 1; return; } if ($type eq "SVGRect") { $implIncludes{"FloatRect.h"} = 1; - $implIncludes{"DOM$type.h"} = 1; + $implIncludes{"DOMSVGRectInternal.h"} = 1; return; } if ($type eq "SVGPoint") { $implIncludes{"FloatPoint.h"} = 1; - $implIncludes{"DOM$type.h"} = 1; + $implIncludes{"DOMSVGPointInternal.h"} = 1; return; } if ($type eq "SVGMatrix") { $implIncludes{"TransformationMatrix.h"} = 1; - $implIncludes{"DOM$type.h"} = 1; + $implIncludes{"DOMSVGMatrixInternal.h"} = 1; $implIncludes{"SVGException.h"} = 1; return; } if ($type eq "SVGNumber") { - $implIncludes{"DOM$type.h"} = 1; + $implIncludes{"DOMSVGNumberInternal.h"} = 1; return; } if ($type =~ /(\w+)(Abs|Rel)$/) { $implIncludes{"$1.h"} = 1; - $implIncludes{"DOM$type.h"} = 1; + $implIncludes{"DOM${type}Internal.h"} = 1; + return; + } + + if ($type eq "NodeFilter") { + $implIncludes{"NodeFilter.h"} = 1; + $implIncludes{"ObjCNodeFilterCondition.h"} = 1; return; } - $implIncludes{"ObjCEventListener.h"} = 1 if $type eq "EventListener"; - $implIncludes{"ObjCNodeFilterCondition.h"} = 1 if $type eq "NodeFilter"; - $implIncludes{"DOMCustomXPathNSResolver.h"} = 1 if $type eq "XPathNSResolver"; + if ($type eq "EventListener") { + $implIncludes{"EventListener.h"} = 1; + $implIncludes{"ObjCEventListener.h"} = 1; + return; + } + + if ($type eq "XPathNSResolver") { + $implIncludes{"DOMCustomXPathNSResolver.h"} = 1; + $implIncludes{"XPathNSResolver.h"} = 1; + return; + } # FIXME: won't compile without these $implIncludes{"CSSMutableStyleDeclaration.h"} = 1 if $type eq "CSSStyleDeclaration"; - $implIncludes{"NamedAttrMap.h"} = 1 if $type eq "NamedNodeMap"; $implIncludes{"NameNodeList.h"} = 1 if $type eq "NodeList"; # Default, include the same named file (the implementation) and the same name prefixed with "DOM". $implIncludes{"$type.h"} = 1; - $implIncludes{"DOM$type.h"} = 1; + $implIncludes{"DOM${type}Internal.h"} = 1; } sub GenerateHeader @@ -692,7 +625,7 @@ sub GenerateHeader my $numFunctions = @{$dataNode->functions}; # - Add default header template - @headerContentHeader = split("\r", $headerLicenceTemplate); + @headerContentHeader = split("\r", $headerLicenseTemplate); push(@headerContentHeader, "\n"); # - INCLUDES - @@ -759,23 +692,6 @@ sub GenerateHeader # - Add attribute getters/setters. if ($numAttributes > 0) { - # Add ivars, if any, first - @ivars = (); - foreach my $attribute (@{$dataNode->attributes}) { - push(@ivars, $attribute) if $attribute->signature->extendedAttributes->{"ObjCIvar"}; - } - - if (@ivars > 0) { - push(@headerContent, "{\n"); - foreach my $attribute (@ivars) { - my $type = GetObjCType($attribute->signature->type); - my $name = "m_" . $attribute->signature->name; - my $ivarDeclaration = "$type $name"; - push(@headerContent, " $ivarDeclaration;\n"); - } - push(@headerContent, "}\n"); - } - foreach my $attribute (@{$dataNode->attributes}) { my $attributeName = $attribute->signature->name; @@ -971,7 +887,7 @@ sub GenerateHeader if (@privateHeaderAttributes > 0 or @privateHeaderFunctions > 0 or exists $alwaysGenerateForNoSVGBuild{$className}) { # - Private category @interface - @privateHeaderContentHeader = split("\r", $headerLicenceTemplate); + @privateHeaderContentHeader = split("\r", $headerLicenseTemplate); push(@privateHeaderContentHeader, "\n"); my $classHeaderName = GetClassHeaderName($className); @@ -991,45 +907,66 @@ sub GenerateHeader unless ($isProtocol) { # Generate internal interfaces my $podType = $dataNode->extendedAttributes->{"PODType"}; - my $typeGetterSig = GetInternalTypeGetterSignature($interfaceName, $podType); - my ($typeMakerSig, $typeMakerSigAddition, $ivarsToInit) = GetInternalTypeMakerSignature($interfaceName, $podType); # Generate interface definitions. - @internalHeaderContent = split("\r", $implementationLicenceTemplate); + @internalHeaderContent = split("\r", $implementationLicenseTemplate); push(@internalHeaderContent, "\n#import <WebCore/$className.h>\n\n"); push(@internalHeaderContent, $interfaceAvailabilityVersionCheck) if length $interfaceAvailabilityVersion; - if ($interfaceName eq "Node" or $interfaceName eq "SVGElementInstance") { + if ($interfaceName eq "Node") { push(@internalHeaderContent, "\@protocol DOMEventTarget;\n\n"); } + my $startedNamespace = 0; + + my $implClassName = GetImplClassName($interfaceName); + if ($codeGenerator->IsSVGAnimatedType($interfaceName)) { push(@internalHeaderContent, "#import <WebCore/SVGAnimatedTemplate.h>\n\n"); } elsif ($interfaceName eq "RGBColor") { push(@internalHeaderContent, "#import <WebCore/Color.h>\n\n"); } else { + push(@internalHeaderContent, "namespace WebCore {\n"); + $startedNamespace = 1; if ($podType and $podType ne "float") { - push(@internalHeaderContent, "namespace WebCore { class $podType; }\n\n"); + push(@internalHeaderContent, " class $podType;\n"); } elsif ($interfaceName eq "Node") { - push(@internalHeaderContent, "namespace WebCore { class Node; class EventTarget; }\n\n"); - } elsif ($interfaceName eq "SVGElementInstance") { - push(@internalHeaderContent, "namespace WebCore { class SVGElementInstance; class EventTarget; }\n\n"); + push(@internalHeaderContent, " class EventTarget;\n class Node;\n"); + } else { + push(@internalHeaderContent, " class $implClassName;\n"); + } + push(@internalHeaderContent, "}\n\n"); + } + + if ($podType) { + if ($podType eq "float") { + push(@internalHeaderContent, "float core($className *);\n"); + } else { + push(@internalHeaderContent, "WebCore::$podType core($className *);\n"); + } + } else { + push(@internalHeaderContent, "WebCore::$implClassName* core($className *);\n"); + } + + if ($podType) { + if ($podType eq "float") { + push(@internalHeaderContent, "$className *kit($podType);\n"); } else { - my $implClassName = GetImplClassName($interfaceName); - push(@internalHeaderContent, "namespace WebCore { class $implClassName; }\n\n"); + push(@internalHeaderContent, "$className *kit(WebCore::$podType);\n"); } + } else { + push(@internalHeaderContent, "$className *kit(WebCore::$implClassName*);\n"); } - push(@internalHeaderContent, "\@interface $className (WebCoreInternal)\n"); - push(@internalHeaderContent, $typeGetterSig . ";\n"); - push(@internalHeaderContent, $typeMakerSig . ";\n"); + if ($dataNode->extendedAttributes->{Polymorphic}) { + push(@internalHeaderContent, "Class kitClass(WebCore::$implClassName*);\n"); + } - if ($interfaceName eq "Node" or $interfaceName eq "SVGElementInstance") { - push(@internalHeaderContent, "+ (id <DOMEventTarget>)_wrapEventTarget:(WebCore::EventTarget *)eventTarget;\n"); + if ($interfaceName eq "Node") { + push(@internalHeaderContent, "id <DOMEventTarget> kit(WebCore::EventTarget*);\n"); } - push(@internalHeaderContent, "\@end\n"); push(@internalHeaderContent, "\n#endif\n") if length $interfaceAvailabilityVersion; } } @@ -1063,7 +1000,7 @@ sub GenerateImplementation } # - Add default header template. - @implContentHeader = split("\r", $implementationLicenceTemplate); + @implContentHeader = split("\r", $implementationLicenseTemplate); # - INCLUDES - push(@implContentHeader, "\n#import \"config.h\"\n"); @@ -1071,13 +1008,25 @@ sub GenerateImplementation my $conditionalString; if ($conditional) { $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")"; - push(@implContentHeader, "\n#if ${conditionalString}\n"); + push(@implContentHeader, "\n#if ${conditionalString}\n\n"); } - push(@implContentHeader, "\n#import \"$classHeaderName.h\"\n\n"); + push(@implContentHeader, "#import \"DOMInternal.h\"\n\n"); + push(@implContentHeader, "#import \"$classHeaderName.h\"\n\n"); + + $implIncludes{"ExceptionHandlers.h"} = 1; + $implIncludes{"ThreadCheck.h"} = 1; + $implIncludes{"WebScriptObjectPrivate.h"} = 1; + $implIncludes{$classHeaderName . "Internal.h"} = 1; + + # FIXME: These includes are only needed when the class is a subclass of one of these polymorphic classes. + $implIncludes{"DOMCSSRuleInternal.h"} = 1; + $implIncludes{"DOMCSSValueInternal.h"} = 1; + $implIncludes{"DOMEventInternal.h"} = 1; + $implIncludes{"DOMNodeInternal.h"} = 1; + $implIncludes{"DOMStyleSheetInternal.h"} = 1; - push(@implContentHeader, "#import \"ThreadCheck.h\"\n"); - push(@implContentHeader, "#import <wtf/GetPtr.h>\n\n"); + $implIncludes{"DOMSVGPathSegInternal.h"} = 1 if $interfaceName =~ /^SVGPathSeg.+/; if ($codeGenerator->IsSVGAnimatedType($interfaceName)) { $implIncludes{"SVGAnimatedTemplate.h"} = 1; @@ -1091,11 +1040,10 @@ sub GenerateImplementation } } - $implIncludes{"DOMInternal.h"} = 1; - $implIncludes{"ExceptionHandlers.h"} = 1; - @implContent = (); + push(@implContent, "#import <wtf/GetPtr.h>\n\n"); + # add implementation accessor if ($podType) { push(@implContent, "#define IMPL reinterpret_cast<$podTypeWithNamespace*>(_internal)\n\n"); @@ -1111,18 +1059,9 @@ sub GenerateImplementation # Only generate 'dealloc' and 'finalize' methods for direct subclasses of DOMObject. if ($parentImplClassName eq "Object") { - my @ivarsToRelease = (); - if (@ivars > 0) { - foreach $attribute (@ivars) { - my $name = "m_" . $attribute->signature->name; - push(@ivarsToRelease, " [$name release];\n"); - } - } - push(@implContent, "- (void)dealloc\n"); push(@implContent, "{\n"); push(@implContent, " $assertMainThread\n"); - push(@implContent, @ivarsToRelease); if ($interfaceName eq "NodeIterator") { push(@implContent, " if (_internal) {\n"); push(@implContent, " [self detach];\n"); @@ -1210,17 +1149,16 @@ sub GenerateImplementation # special case for EventTarget protocol $attributeTypeSansPtr = "DOMNode" if $idlType eq "EventTarget"; - my $typeMaker = GetObjCTypeMaker($attribute->signature->type); - # Special cases my @customGetterContent = (); if ($attributeTypeSansPtr eq "DOMImplementation") { # FIXME: We have to special case DOMImplementation until DOMImplementationFront is removed - $getterContentHead = "[$attributeTypeSansPtr $typeMaker:implementationFront(IMPL"; - $getterContentTail .= "]"; + $getterContentHead = "kit(implementationFront(IMPL"; + $getterContentTail .= ")"; } elsif ($attributeName =~ /(\w+)DisplayString$/) { my $attributeToDisplay = $1; - $getterContentHead = "WebCore::displayString(IMPL->$attributeToDisplay(), [self _element]"; + $getterContentHead = "WebCore::displayString(IMPL->$attributeToDisplay(), core(self)"; + $implIncludes{"HitTestResult.h"} = 1; } elsif ($attributeName =~ /^absolute(\w+)URL$/) { my $typeOfURL = $1; $getterContentHead = "[self _getURLAttribute:"; @@ -1245,15 +1183,14 @@ sub GenerateImplementation } elsif ($attribute->signature->extendedAttributes->{"ConvertFromString"}) { $getterContentTail .= ".toInt()"; } elsif ($codeGenerator->IsPodType($idlType)) { - $getterContentHead = "[$attributeTypeSansPtr $typeMaker:" . $getterContentHead; - $getterContentTail .= "]"; + $getterContentHead = "kit($getterContentHead"; + $getterContentTail .= ")"; } elsif (IsProtocolType($idlType) and $idlType ne "EventTarget") { - $getterContentHead = "[$attributeClassName $typeMaker:WTF::getPtr(" . $getterContentHead; - $getterContentTail .= ")]"; - } elsif ($typeMaker ne "") { - # Surround getter with TypeMaker - $getterContentHead = "[$attributeTypeSansPtr $typeMaker:WTF::getPtr(" . $getterContentHead; - $getterContentTail .= ")]"; + $getterContentHead = "kit($getterContentHead"; + $getterContentTail .= ")"; + } elsif (ConversionNeeded($attribute->signature->type)) { + $getterContentHead = "kit(WTF::getPtr($getterContentHead"; + $getterContentTail .= "))"; } my $getterContent; @@ -1390,7 +1327,7 @@ sub GenerateImplementation push(@functionContent, " RefPtr<WebCore::XPathNSResolver> customResolver;\n"); push(@functionContent, " if ($paramName) {\n"); push(@functionContent, " if ([$paramName isMemberOfClass:[DOMNativeXPathNSResolver class]])\n"); - push(@functionContent, " nativeResolver = [(DOMNativeXPathNSResolver *)$paramName _xpathNSResolver];\n"); + push(@functionContent, " nativeResolver = core(static_cast<DOMNativeXPathNSResolver *>($paramName));\n"); push(@functionContent, " else {\n"); push(@functionContent, " customResolver = WebCore::DOMCustomXPathNSResolver::create($paramName);\n"); push(@functionContent, " nativeResolver = WTF::getPtr(customResolver);\n"); @@ -1402,7 +1339,7 @@ sub GenerateImplementation if (defined $needsCustom{"EventTarget"}) { my $paramName = $needsCustom{"EventTarget"}; push(@functionContent, " DOMNode* ${paramName}ObjC = $paramName;\n"); - push(@functionContent, " WebCore::Node* ${paramName}Node = [${paramName}ObjC _node];\n"); + push(@functionContent, " WebCore::Node* ${paramName}Node = core(${paramName}ObjC);\n"); $implIncludes{"DOMNode.h"} = 1; $implIncludes{"Node.h"} = 1; } @@ -1443,14 +1380,14 @@ sub GenerateImplementation push(@functionContent, " if (x == 0.0 || y == 0.0)\n"); push(@functionContent, " ec = WebCore::SVGException::SVG_INVALID_VALUE_ERR;\n"); push(@functionContent, " $exceptionRaiseOnError\n"); - push(@functionContent, " return [DOMSVGMatrix _wrapSVGMatrix:$content];\n"); + push(@functionContent, " return kit($content);\n"); } elsif ($svgMatrixInverse) { # Special case with inverse & SVGMatrix push(@functionContent, " $exceptionInit\n"); push(@functionContent, " if (!$caller->isInvertible())\n"); push(@functionContent, " ec = WebCore::SVGException::SVG_MATRIX_NOT_INVERTABLE;\n"); push(@functionContent, " $exceptionRaiseOnError\n"); - push(@functionContent, " return [DOMSVGMatrix _wrapSVGMatrix:$content];\n"); + push(@functionContent, " return kit($content);\n"); } elsif ($svgLengthConvertToSpecifiedUnits) { push(@functionContent, " IMPL->convertToSpecifiedUnits(inUnitType, 0 /* FIXME */);\n"); } elsif ($returnType eq "void") { @@ -1478,26 +1415,11 @@ sub GenerateImplementation push(@functionContent, " return nil;\n"); } } else { - my $typeMaker = GetObjCTypeMaker($function->signature->type); - unless ($typeMaker eq "") { - my $returnTypeClass = ""; - if ($function->signature->type eq "XPathNSResolver") { - # Special case XPathNSResolver - $returnTypeClass = "DOMNativeXPathNSResolver"; - } else { - # Remove trailing " *" from pointer types. - $returnTypeClass = $returnType; - $returnTypeClass =~ s/ \*$//; - } - - # Surround getter with TypeMaker - my $idlType = $returnTypeClass; - $idlType =~ s/^DOM//; - - if ($codeGenerator->IsPodType($idlType)) { - $content = "[$returnTypeClass $typeMaker:" . $content . "]"; + if (ConversionNeeded($function->signature->type)) { + if ($codeGenerator->IsPodType($function->signature->type)) { + $content = "kit($content)"; } else { - $content = "[$returnTypeClass $typeMaker:WTF::getPtr(" . $content . ")]"; + $content = "kit(WTF::getPtr($content))"; } } @@ -1544,87 +1466,55 @@ sub GenerateImplementation push(@implContent, "\@end\n"); # Generate internal interfaces - unless ($dataNode->extendedAttributes->{ObjCCustomInternalImpl}) { - # - BEGIN WebCoreInternal category @implementation - push(@implContent, "\n\@implementation $className (WebCoreInternal)\n\n"); - - my $typeGetterSig = GetInternalTypeGetterSignature($interfaceName, $podType); - push(@implContent, "$typeGetterSig\n"); + if ($podType) { + my $prefixedPodType = $podType eq "float" ? $podType : "WebCore::$podType"; + push(@implContent, "\n$prefixedPodType core($className *wrapper)\n"); push(@implContent, "{\n"); - - if ($podType) { - push(@implContent, " return *IMPL;\n"); - } else { - push(@implContent, " return IMPL;\n"); - } - + push(@implContent, " return wrapper ? *reinterpret_cast<$prefixedPodType*>(wrapper->_internal) : $prefixedPodType();\n"); push(@implContent, "}\n\n"); + } else { + push(@implContent, "\nWebCore::$implClassName* core($className *wrapper)\n"); + push(@implContent, "{\n"); + push(@implContent, " return wrapper ? reinterpret_cast<WebCore::$implClassName*>(wrapper->_internal) : 0;\n"); + push(@implContent, "}\n\n"); + } - my ($typeMakerSig, $typeMakerSigAddition, $ivarsToInit) = GetInternalTypeMakerSignature($interfaceName, $podType); - - if ($podType) { - # - (id)_initWithFooBar:(WebCore::FooBar)impl for implementation class FooBar - my $initWithImplName = "_initWith" . $implClassName; - my $initWithSig = "- (id)$initWithImplName:($podTypeWithNamespace)impl" . $typeMakerSigAddition; - - # FIXME: Implement Caching - push(@implContent, "$initWithSig\n"); - push(@implContent, "{\n"); - push(@implContent, " $assertMainThread;\n"); - push(@implContent, " [super _init];\n"); - push(@implContent, " $podTypeWithNamespace* _impl = new $podTypeWithNamespace(impl);\n"); - push(@implContent, " _internal = reinterpret_cast<DOMObjectInternal*>(_impl);\n"); - push(@implContent, " return self;\n"); - push(@implContent, "}\n\n"); - - # - (DOMFooBar)_wrapFooBar:(WebCore::FooBar)impl for implementation class FooBar - push(@implContent, "$typeMakerSig\n"); - push(@implContent, "{\n"); - push(@implContent, " $assertMainThread;\n"); - push(@implContent, " return [[[self alloc] $initWithImplName:impl] autorelease];\n"); - push(@implContent, "}\n\n"); - } elsif ($parentImplClassName eq "Object") { - # - (id)_initWithFooBar:(WebCore::FooBar *)impl for implementation class FooBar - my $initWithImplName = "_initWith" . $implClassName; - my $initWithSig = "- (id)$initWithImplName:($implClassNameWithNamespace *)impl" . $typeMakerSigAddition; - - push(@implContent, "$initWithSig\n"); - push(@implContent, "{\n"); - push(@implContent, " $assertMainThread;\n"); - push(@implContent, " [super _init];\n"); - push(@implContent, " _internal = reinterpret_cast<DOMObjectInternal*>(impl);\n"); - push(@implContent, " impl->ref();\n"); - push(@implContent, " WebCore::addDOMWrapper(self, impl);\n"); - push(@implContent, @ivarsToRetain); - push(@implContent, " return self;\n"); - push(@implContent, "}\n\n"); - - # - (DOMFooBar)_wrapFooBar:(WebCore::FooBar *)impl for implementation class FooBar - push(@implContent, "$typeMakerSig\n"); - push(@implContent, "{\n"); - push(@implContent, " $assertMainThread;\n"); - push(@implContent, " if (!impl)\n"); + if ($podType) { + # FIXME: Implement caching. + my $prefixedPodType = $podType eq "float" ? $podType : "WebCore::$podType"; + push(@implContent, "$className *kit($prefixedPodType value)\n"); + push(@implContent, "{\n"); + push(@implContent, " $assertMainThread;\n"); + push(@implContent, " $className *wrapper = [[$className alloc] _init];\n"); + push(@implContent, " wrapper->_internal = reinterpret_cast<DOMObjectInternal*>(new $prefixedPodType(value));\n"); + push(@implContent, " return [wrapper autorelease];\n"); + push(@implContent, "}\n"); + } elsif ($parentImplClassName eq "Object") { + push(@implContent, "$className *kit(WebCore::$implClassName* value)\n"); + push(@implContent, "{\n"); + push(@implContent, " $assertMainThread;\n"); + push(@implContent, " if (!value)\n"); + push(@implContent, " return nil;\n"); + push(@implContent, " if ($className *wrapper = getDOMWrapper(value))\n"); + push(@implContent, " return [[wrapper retain] autorelease];\n"); + if ($dataNode->extendedAttributes->{Polymorphic}) { + push(@implContent, " $className *wrapper = [[kitClass(value) alloc] _init];\n"); + push(@implContent, " if (!wrapper)\n"); push(@implContent, " return nil;\n"); - push(@implContent, " id cachedInstance;\n"); - push(@implContent, " cachedInstance = WebCore::getDOMWrapper(impl);\n"); - push(@implContent, " if (cachedInstance)\n"); - push(@implContent, " return [[cachedInstance retain] autorelease];\n"); - push(@implContent, " return [[[self alloc] $initWithImplName:impl" . $ivarsToInit . "] autorelease];\n"); - push(@implContent, "}\n\n"); } else { - my $internalBaseType = "DOM$baseClass"; - my $internalBaseTypeMaker = GetObjCTypeMaker($baseClass); - - # - (DOMFooBar)_wrapFooBar:(WebCore::FooBar *)impl for implementation class FooBar - push(@implContent, "$typeMakerSig\n"); - push(@implContent, "{\n"); - push(@implContent, " $assertMainThread;\n"); - push(@implContent, " return static_cast<$className*>([$internalBaseType $internalBaseTypeMaker:impl]);\n"); - push(@implContent, "}\n\n"); + push(@implContent, " $className *wrapper = [[$className alloc] _init];\n"); } - - # END WebCoreInternal category - push(@implContent, "\@end\n"); + push(@implContent, " wrapper->_internal = reinterpret_cast<DOMObjectInternal*>(value);\n"); + push(@implContent, " value->ref();\n"); + push(@implContent, " addDOMWrapper(wrapper, value);\n"); + push(@implContent, " return [wrapper autorelease];\n"); + push(@implContent, "}\n"); + } else { + push(@implContent, "$className *kit(WebCore::$implClassName* value)\n"); + push(@implContent, "{\n"); + push(@implContent, " $assertMainThread;\n"); + push(@implContent, " return static_cast<$className*>(kit(static_cast<WebCore::$baseClass*>(value)));\n"); + push(@implContent, "}\n"); } # - End the ifdef conditional if necessary @@ -1692,8 +1582,6 @@ sub WriteData print IMPL @implContentHeader; print IMPL map { "#import \"$_\"\n" } sort keys(%implIncludes); - - print IMPL "\n" if keys(%implIncludes); print IMPL @implContent; close(IMPL); diff --git a/WebCore/bindings/v8/ScheduledAction.cpp b/WebCore/bindings/v8/ScheduledAction.cpp index 7c71d00..ab51600 100644 --- a/WebCore/bindings/v8/ScheduledAction.cpp +++ b/WebCore/bindings/v8/ScheduledAction.cpp @@ -34,9 +34,13 @@ #include "Document.h" #include "ScriptExecutionContext.h" #include "ScriptSourceCode.h" +#include "ScriptValue.h" #include "V8Binding.h" #include "V8Proxy.h" +#include "WorkerContext.h" +#include "WorkerContextExecutionProxy.h" +#include "WorkerThread.h" namespace WebCore { @@ -86,10 +90,20 @@ ScheduledAction::~ScheduledAction() void ScheduledAction::execute(ScriptExecutionContext* context) { - // FIXME: Timeouts for running the javascript code are not set. V8Proxy* proxy = V8Proxy::retrieve(context); - if (!proxy) - return; + if (proxy) + execute(proxy); +#if ENABLE(WORKERS) + else { + ASSERT(context->isWorkerContext()); + execute(static_cast<WorkerContext*>(context)); + } +#endif +} + +void ScheduledAction::execute(V8Proxy* proxy) +{ + ASSERT(proxy); v8::HandleScope handleScope; v8::Local<v8::Context> v8Context = proxy->GetContext(); @@ -100,15 +114,33 @@ void ScheduledAction::execute(ScriptExecutionContext* context) proxy->setTimerCallback(true); - if (!m_function.IsEmpty() && m_function->IsFunction()) + // FIXME: Need to implement timeouts for preempting a long-running script. + if (!m_function.IsEmpty() && m_function->IsFunction()) { proxy->CallFunction(v8::Persistent<v8::Function>::Cast(m_function), v8Context->Global(), m_argc, m_argv); - else + Document::updateStyleForAllDocuments(); + } else proxy->evaluate(m_code, 0); - if (context->isDocument()) - static_cast<Document*>(context)->updateRendering(); - proxy->setTimerCallback(false); } +#if ENABLE(WORKERS) +void ScheduledAction::execute(WorkerContext* workerContext) +{ + // In a Worker, the execution should always happen on a worker thread. + ASSERT(workerContext->thread()->threadID() == currentThread()); + + WorkerScriptController* scriptController = workerContext->script(); + + if (!m_function.IsEmpty() && m_function->IsFunction()) { + v8::HandleScope handleScope; + v8::Local<v8::Context> v8Context = scriptController->proxy()->GetContext(); + ASSERT(!v8Context.IsEmpty()); + v8::Context::Scope scope(v8Context); + m_function->Call(v8Context->Global(), m_argc, m_argv); + } else + scriptController->evaluate(m_code); +} +#endif + } // namespace WebCore diff --git a/WebCore/bindings/v8/ScheduledAction.h b/WebCore/bindings/v8/ScheduledAction.h index da6cb02..53694c7 100644 --- a/WebCore/bindings/v8/ScheduledAction.h +++ b/WebCore/bindings/v8/ScheduledAction.h @@ -39,14 +39,16 @@ namespace WebCore { class String; class ScriptExecutionContext; + class V8Proxy; + class WorkerContext; class ScheduledAction { public: ScheduledAction(v8::Handle<v8::Function>, int argc, v8::Handle<v8::Value> argv[]); - explicit ScheduledAction(const WebCore::String& code) + explicit ScheduledAction(const WebCore::String& code, const KURL& url = KURL()) : m_argc(0) , m_argv(0) - , m_code(code) + , m_code(code, url) { } @@ -54,6 +56,11 @@ namespace WebCore { virtual void execute(ScriptExecutionContext*); private: + void execute(V8Proxy*); +#if ENABLE(WORKERS) + void execute(WorkerContext*); +#endif + v8::Persistent<v8::Function> m_function; int m_argc; v8::Persistent<v8::Value>* m_argv; diff --git a/WebCore/bindings/v8/ScriptController.cpp b/WebCore/bindings/v8/ScriptController.cpp new file mode 100644 index 0000000..9ecf3ab --- /dev/null +++ b/WebCore/bindings/v8/ScriptController.cpp @@ -0,0 +1,391 @@ +/* + * Copyright (C) 2008, 2009 Google Inc. All rights reserved. + * Copyright (C) 2009 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "ScriptController.h" + +#include "ChromiumBridge.h" +#include "CString.h" +#include "Document.h" +#include "DOMWindow.h" +#include "Event.h" +#include "EventListener.h" +#include "EventNames.h" +#include "Frame.h" +#include "Node.h" +#include "NotImplemented.h" +#include "npruntime_priv.h" +#include "NPV8Object.h" +#include "ScriptSourceCode.h" +#include "ScriptState.h" +#include "Widget.h" + +#include "V8Binding.h" +#include "V8NPObject.h" +#include "V8Proxy.h" + +namespace WebCore { + +void ScriptController::setFlags(const char* string, int length) +{ + v8::V8::SetFlagsFromString(string, length); +} + +Frame* ScriptController::retrieveFrameForEnteredContext() +{ + return V8Proxy::retrieveFrameForEnteredContext(); +} + +Frame* ScriptController::retrieveFrameForCurrentContext() +{ + return V8Proxy::retrieveFrameForCurrentContext(); +} + +bool ScriptController::isSafeScript(Frame* target) +{ + return V8Proxy::CanAccessFrame(target, true); +} + +void ScriptController::gcProtectJSWrapper(void* domObject) +{ + V8Proxy::GCProtect(domObject); +} + +void ScriptController::gcUnprotectJSWrapper(void* domObject) +{ + V8Proxy::GCUnprotect(domObject); +} + +ScriptController::ScriptController(Frame* frame) + : m_frame(frame) + , m_sourceURL(0) + , m_processingTimerCallback(false) + , m_paused(false) + , m_scriptState(new ScriptState(frame)) + , m_proxy(new V8Proxy(frame)) +#if ENABLE(NETSCAPE_PLUGIN_API) + , m_windowScriptNPObject(0) +#endif +{ +} + +ScriptController::~ScriptController() +{ + m_proxy->disconnectFrame(); +} + +void ScriptController::clearScriptObjects() +{ + PluginObjectMap::iterator it = m_pluginObjects.begin(); + for (; it != m_pluginObjects.end(); ++it) { + _NPN_UnregisterObject(it->second); + NPN_ReleaseObject(it->second); + } + m_pluginObjects.clear(); + +#if ENABLE(NETSCAPE_PLUGIN_API) + if (m_windowScriptNPObject) { + // Call _NPN_DeallocateObject() instead of _NPN_ReleaseObject() so that we don't leak if a plugin fails to release the window + // script object properly. + // This shouldn't cause any problems for plugins since they should have already been stopped and destroyed at this point. + _NPN_DeallocateObject(m_windowScriptNPObject); + m_windowScriptNPObject = 0; + } +#endif +} + +void ScriptController::updateSecurityOrigin() +{ + m_proxy->updateSecurityOrigin(); +} + +void ScriptController::updatePlatformScriptObjects() +{ + notImplemented(); +} + +bool ScriptController::processingUserGesture() const +{ + Frame* activeFrame = V8Proxy::retrieveFrameForEnteredContext(); + // No script is running, so it must be run by users. + if (!activeFrame) + return true; + + V8Proxy* activeProxy = activeFrame->script()->proxy(); + + v8::HandleScope handleScope; + v8::Handle<v8::Context> context = V8Proxy::GetContext(activeFrame); + // FIXME: find all cases context can be empty: + // 1) JS is disabled; + // 2) page is NULL; + if (context.IsEmpty()) + return true; + + v8::Context::Scope scope(context); + + v8::Handle<v8::Object> global = context->Global(); + v8::Handle<v8::Value> jsEvent = global->Get(v8::String::NewSymbol("event")); + Event* event = V8Proxy::ToNativeEvent(jsEvent); + + // Based on code from kjs_bindings.cpp. + // Note: This is more liberal than Firefox's implementation. + if (event) { + const AtomicString& type = event->type(); + bool eventOk = + // mouse events + type == eventNames().clickEvent || type == eventNames().mousedownEvent || type == eventNames().mouseupEvent || type == eventNames().dblclickEvent + // keyboard events + || type == eventNames().keydownEvent || type == eventNames().keypressEvent || type == eventNames().keyupEvent + // other accepted events + || type == eventNames().selectEvent || type == eventNames().changeEvent || type == eventNames().focusEvent || type == eventNames().blurEvent || type == eventNames().submitEvent; + + if (eventOk) + return true; + } else if (activeProxy->inlineCode() && !activeProxy->timerCallback()) { + // 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; +} + +void ScriptController::evaluateInNewContext(const Vector<ScriptSourceCode>& sources) +{ + m_proxy->evaluateInNewContext(sources); +} + +// Evaluate a script file in the environment of this proxy. +ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode) +{ + v8::HandleScope handleScope; + v8::Handle<v8::Context> context = V8Proxy::GetContext(m_proxy->frame()); + if (context.IsEmpty()) + return ScriptValue(); + + v8::Context::Scope scope(context); + + RefPtr<Frame> protect(m_frame); + + v8::Local<v8::Value> object = m_proxy->evaluate(sourceCode, 0); + + // Evaluating the JavaScript could cause the frame to be deallocated + // so we start the keep alive timer here. + m_frame->keepAlive(); + + if (object.IsEmpty() || object->IsUndefined()) + return ScriptValue(); + + return ScriptValue(object); +} + +void ScriptController::setEventHandlerLineNumber(int lineNumber) +{ + m_proxy->setEventHandlerLineno(lineNumber); +} + +void ScriptController::finishedWithEvent(Event* event) +{ + m_proxy->finishedWithEvent(event); +} + +// Create a V8 object with an interceptor of NPObjectPropertyGetter. +void ScriptController::bindToWindowObject(Frame* frame, const String& key, NPObject* object) +{ + v8::HandleScope handleScope; + + v8::Handle<v8::Context> context = V8Proxy::GetContext(frame); + if (context.IsEmpty()) + return; + + v8::Context::Scope scope(context); + + v8::Handle<v8::Object> value = CreateV8ObjectForNPObject(object, 0); + + // Attach to the global object. + v8::Handle<v8::Object> global = context->Global(); + global->Set(v8String(key), value); +} + +void ScriptController::collectGarbage() +{ + v8::HandleScope handleScope; + v8::Handle<v8::Context> context = V8Proxy::GetContext(m_proxy->frame()); + if (context.IsEmpty()) + return; + + v8::Context::Scope scope(context); + + m_proxy->evaluate(ScriptSourceCode("if (window.gc) void(gc());"), 0); +} + +bool ScriptController::haveInterpreter() const +{ + return m_proxy->ContextInitialized(); +} + +bool ScriptController::isEnabled() const +{ + return m_proxy->isEnabled(); +} + +PassScriptInstance ScriptController::createScriptInstanceForWidget(Widget* widget) +{ + ASSERT(widget); + + if (widget->isFrameView()) + return 0; + + NPObject* npObject = ChromiumBridge::pluginScriptableObject(widget); + if (!npObject) + return 0; + + // Frame Memory Management for NPObjects + // ------------------------------------- + // NPObjects are treated differently than other objects wrapped by JS. + // NPObjects can be created either by the browser (e.g. the main + // window object) or by the plugin (the main plugin object + // for a HTMLEmbedElement). Further, unlike most DOM Objects, the frame + // is especially careful to ensure NPObjects terminate at frame teardown because + // if a plugin leaks a reference, it could leak its objects (or the browser's objects). + // + // The Frame maintains a list of plugin objects (m_pluginObjects) + // which it can use to quickly find the wrapped embed object. + // + // Inside the NPRuntime, we've added a few methods for registering + // wrapped NPObjects. The purpose of the registration is because + // javascript garbage collection is non-deterministic, yet we need to + // be able to tear down the plugin objects immediately. When an object + // is registered, javascript can use it. When the object is destroyed, + // or when the object's "owning" object is destroyed, the object will + // be un-registered, and the javascript engine must not use it. + // + // Inside the javascript engine, the engine can keep a reference to the + // NPObject as part of its wrapper. However, before accessing the object + // it must consult the NPN_Registry. + + v8::Local<v8::Object> wrapper = CreateV8ObjectForNPObject(npObject, 0); + + // Track the plugin object. We've been given a reference to the object. + m_pluginObjects.set(widget, npObject); + + return V8ScriptInstance::create(wrapper); +} + +void ScriptController::cleanupScriptObjectsForPlugin(void* nativeHandle) +{ + PluginObjectMap::iterator it = m_pluginObjects.find(nativeHandle); + if (it == m_pluginObjects.end()) + return; + _NPN_UnregisterObject(it->second); + NPN_ReleaseObject(it->second); + m_pluginObjects.remove(it); +} + +static NPObject* createNoScriptObject() +{ + notImplemented(); + return 0; +} + +static NPObject* createScriptObject(Frame* frame) +{ + v8::HandleScope handleScope; + v8::Handle<v8::Context> context = V8Proxy::GetContext(frame); + if (context.IsEmpty()) + return createNoScriptObject(); + + v8::Context::Scope scope(context); + DOMWindow* window = frame->domWindow(); + v8::Handle<v8::Value> global = V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, window); + ASSERT(global->IsObject()); + return npCreateV8ScriptObject(0, v8::Handle<v8::Object>::Cast(global), window); +} + +NPObject* ScriptController::windowScriptNPObject() +{ + if (m_windowScriptNPObject) + return m_windowScriptNPObject; + + if (isEnabled()) { + // JavaScript is enabled, so there is a JavaScript window object. + // Return an NPObject bound to the window object. + m_windowScriptNPObject = createScriptObject(m_frame); + _NPN_RegisterObject(m_windowScriptNPObject, 0); + } else { + // JavaScript is not enabled, so we cannot bind the NPObject to the + // JavaScript window object. Instead, we create an NPObject of a + // different class, one which is not bound to a JavaScript object. + m_windowScriptNPObject = createNoScriptObject(); + } + return m_windowScriptNPObject; +} + +NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement* plugin) +{ + // Can't create NPObjects when JavaScript is disabled. + if (!isEnabled()) + return createNoScriptObject(); + + v8::HandleScope handleScope; + v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame); + if (context.IsEmpty()) + return createNoScriptObject(); + v8::Context::Scope scope(context); + + DOMWindow* window = m_frame->domWindow(); + v8::Handle<v8::Value> v8plugin = V8Proxy::ToV8Object(V8ClassIndex::HTMLEMBEDELEMENT, plugin); + if (!v8plugin->IsObject()) + return createNoScriptObject(); + + return npCreateV8ScriptObject(0, v8::Handle<v8::Object>::Cast(v8plugin), window); +} + + +void ScriptController::clearWindowShell() +{ + // V8 binding expects ScriptController::clearWindowShell only be called + // when a frame is loading a new page. V8Proxy::clearForNavigation + // creates a new context for the new page. + m_proxy->clearForNavigation(); +} + +void ScriptController::attachDebugger(void*) +{ + notImplemented(); +} + +void ScriptController::updateDocument() +{ + m_proxy->updateDocument(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptController.h b/WebCore/bindings/v8/ScriptController.h new file mode 100644 index 0000000..17703b5 --- /dev/null +++ b/WebCore/bindings/v8/ScriptController.h @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2008, 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 ScriptController_h +#define ScriptController_h + +#include "ScriptInstance.h" +#include "ScriptValue.h" + +#include "V8Proxy.h" + +#include <v8.h> + +#include <wtf/HashMap.h> +#include <wtf/Vector.h> + +namespace WebCore { + class Event; + class Frame; + class HTMLPlugInElement; + class ScriptSourceCode; + class ScriptState; + class String; + class Widget; + + class ScriptController { + public: + ScriptController(Frame*); + ~ScriptController(); + + // FIXME: V8Proxy should either be folded into ScriptController + // or this accessor should be made JSProxy* + V8Proxy* proxy() { return m_proxy.get(); } + + // Evaluate a script file in the environment of this proxy. + // If succeeded, 'succ' is set to true and result is returned + // as a string. + ScriptValue evaluate(const ScriptSourceCode&); + + // Executes JavaScript in a new context associated with the web frame. The + // script gets its own global scope and its own prototypes for intrinsic + // JavaScript objects (String, Array, and so-on). It shares the wrappers for + // all DOM nodes and DOM constructors. + void evaluateInNewContext(const Vector<ScriptSourceCode>&); + + // JSC has a WindowShell object, but for V8, the ScriptController + // is the WindowShell. + bool haveWindowShell() const { return true; } + + // Masquerade 'this' as the windowShell. + // This is a bit of a hack, but provides reasonable compatibility + // with what JSC does as well. + ScriptController* windowShell() { return this; } + + ScriptState* state() const { return m_scriptState.get(); } + + void collectGarbage(); + + // Creates a property of the global object of a frame. + void bindToWindowObject(Frame*, const String& key, NPObject*); + + PassScriptInstance createScriptInstanceForWidget(Widget*); + + // Check if the javascript engine has been initialized. + bool haveInterpreter() const; + + bool isEnabled() const; + + // FIXME: void* is a compile hack. + void attachDebugger(void*); + + // --- Static methods assume we are running VM in single thread, --- + // --- and there is only one VM instance. --- + + // Returns the frame for the entered context. See comments in + // V8Proxy::retrieveFrameForEnteredContext() for more information. + static Frame* retrieveFrameForEnteredContext(); + + // Returns the frame for the current context. See comments in + // V8Proxy::retrieveFrameForEnteredContext() for more information. + static Frame* retrieveFrameForCurrentContext(); + + // Check whether it is safe to access a frame in another domain. + static bool isSafeScript(Frame*); + + // Pass command-line flags to the JS engine. + static void setFlags(const char* string, int length); + + // Protect and unprotect the JS wrapper from garbage collected. + static void gcProtectJSWrapper(void*); + static void gcUnprotectJSWrapper(void*); + + void finishedWithEvent(Event*); + void setEventHandlerLineNumber(int lineNumber); + + void setProcessingTimerCallback(bool processingTimerCallback) { m_processingTimerCallback = processingTimerCallback; } + bool processingUserGesture() const; + + void setPaused(bool paused) { m_paused = paused; } + bool isPaused() const { return m_paused; } + + const String* sourceURL() const { return m_sourceURL; } // 0 if we are not evaluating any script. + + void clearWindowShell(); + void updateDocument(); + + void updateSecurityOrigin(); + void clearScriptObjects(); + void updatePlatformScriptObjects(); + void cleanupScriptObjectsForPlugin(void*); + +#if ENABLE(NETSCAPE_PLUGIN_API) + NPObject* createScriptObjectForPluginElement(HTMLPlugInElement*); + NPObject* windowScriptNPObject(); +#endif + + private: + Frame* m_frame; + const String* m_sourceURL; + + bool m_processingTimerCallback; + bool m_paused; + + OwnPtr<ScriptState> m_scriptState; + OwnPtr<V8Proxy> m_proxy; + typedef HashMap<void*, NPObject*> PluginObjectMap; + + // A mapping between Widgets and their corresponding script object. + // This list is used so that when the plugin dies, we can immediately + // invalidate all sub-objects which are associated with that plugin. + // The frame keeps a NPObject reference for each item on the list. + PluginObjectMap m_pluginObjects; +#if ENABLE(NETSCAPE_PLUGIN_API) + NPObject* m_windowScriptNPObject; +#endif + }; + +} // namespace WebCore + +#endif // ScriptController_h diff --git a/WebCore/bindings/v8/ScriptEventListener.cpp b/WebCore/bindings/v8/ScriptEventListener.cpp new file mode 100644 index 0000000..42c2529 --- /dev/null +++ b/WebCore/bindings/v8/ScriptEventListener.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "ScriptEventListener.h" + +#include "Attribute.h" +#include "Document.h" +#include "Frame.h" + +namespace WebCore { + +PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node* node, Attribute* attr) +{ + ASSERT(node); + + Frame* frame = node->document()->frame(); + + if (!frame) + return 0; + + return V8LazyEventListener::create(frame, attr->value(), attr->localName().string(), node->isSVGElement()); +} + +PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, Attribute* attr) +{ + if (!frame) + return 0; + + return V8LazyEventListener::create(frame, attr->value(), attr->localName().string(), frame->document()->isSVGDocument()); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptEventListener.h b/WebCore/bindings/v8/ScriptEventListener.h new file mode 100644 index 0000000..0171120 --- /dev/null +++ b/WebCore/bindings/v8/ScriptEventListener.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 ScriptEventListener_h +#define ScriptEventListener_h + +#include "V8LazyEventListener.h" + +#include <wtf/PassRefPtr.h> + +namespace WebCore { + + class Attribute; + class Frame; + class Node; + + PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node*, Attribute*); + PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame*, Attribute*); + +} // namespace WebCore + +#endif // ScriptEventListener_h diff --git a/WebCore/bindings/v8/ScriptFunctionCall.cpp b/WebCore/bindings/v8/ScriptFunctionCall.cpp new file mode 100644 index 0000000..d2f7a52 --- /dev/null +++ b/WebCore/bindings/v8/ScriptFunctionCall.cpp @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "ScriptFunctionCall.h" + +#include "Document.h" +#include "Frame.h" +#include "ScriptScope.h" +#include "ScriptState.h" +#include "ScriptString.h" +#include "ScriptValue.h" + +#include "V8Binding.h" +#include "V8Proxy.h" + +#include <v8.h> +#include <wtf/OwnArrayPtr.h> + +namespace WebCore { + +static void reportException(ScriptState* scriptState, v8::TryCatch &exceptionCatcher) +{ + v8::Local<v8::Message> message = exceptionCatcher.Message(); + scriptState->frame()->document()->reportException(toWebCoreString(message->Get()), message->GetLineNumber(), toWebCoreString(message->GetScriptResourceName())); + exceptionCatcher.Reset(); +} + +ScriptFunctionCall::ScriptFunctionCall(ScriptState* scriptState, const ScriptObject& thisObject, const String& name) + : m_scriptState(scriptState) + , m_thisObject(thisObject) + , m_name(name) +{ +} + +void ScriptFunctionCall::appendArgument(const ScriptObject& argument) +{ + m_arguments.append(argument); +} + +void ScriptFunctionCall::appendArgument(const ScriptString& argument) +{ + ScriptScope scope(m_scriptState); + m_arguments.append(v8String(argument)); +} + +void ScriptFunctionCall::appendArgument(const ScriptValue& argument) +{ + m_arguments.append(argument); +} + +void ScriptFunctionCall::appendArgument(const String& argument) +{ + ScriptScope scope(m_scriptState); + m_arguments.append(v8String(argument)); +} + +void ScriptFunctionCall::appendArgument(long long argument) +{ + ScriptScope scope(m_scriptState); + m_arguments.append(v8::Number::New(argument)); +} + +void ScriptFunctionCall::appendArgument(unsigned int argument) +{ + ScriptScope scope(m_scriptState); + m_arguments.append(v8::Number::New(argument)); +} + +void ScriptFunctionCall::appendArgument(int argument) +{ + ScriptScope scope(m_scriptState); + m_arguments.append(v8::Number::New(argument)); +} + +void ScriptFunctionCall::appendArgument(bool argument) +{ + m_arguments.append(v8Boolean(argument)); +} + +ScriptValue ScriptFunctionCall::call(bool& hadException, bool reportExceptions) +{ + ScriptScope scope(m_scriptState, reportExceptions); + + v8::Local<v8::Object> thisObject = m_thisObject.v8Object(); + v8::Local<v8::Value> value = thisObject->Get(v8String(m_name)); + if (!scope.success()) { + hadException = true; + return ScriptValue(); + } + + ASSERT(value->IsFunction()); + + v8::Local<v8::Function> function(v8::Function::Cast(*value)); + OwnArrayPtr<v8::Handle<v8::Value> > args(new v8::Handle<v8::Value>[m_arguments.size()]); + for (size_t i = 0; i < m_arguments.size(); ++i) + args[i] = m_arguments[i].v8Value(); + + v8::Local<v8::Value> result = function->Call(thisObject, m_arguments.size(), args.get()); + if (!scope.success()) { + hadException = true; + return ScriptValue(); + } + + return ScriptValue(result); +} + +ScriptValue ScriptFunctionCall::call() +{ + bool hadException = false; + return call(hadException); +} + +ScriptObject ScriptFunctionCall::construct(bool& hadException, bool reportExceptions) +{ + ScriptScope scope(m_scriptState, reportExceptions); + + v8::Local<v8::Object> thisObject = m_thisObject.v8Object(); + v8::Local<v8::Value> value = thisObject->Get(v8String(m_name)); + if (!scope.success()) { + hadException = true; + return ScriptObject(); + } + + ASSERT(value->IsFunction()); + + v8::Local<v8::Function> constructor(v8::Function::Cast(*value)); + OwnArrayPtr<v8::Handle<v8::Value> > args(new v8::Handle<v8::Value>[m_arguments.size()]); + for (size_t i = 0; i < m_arguments.size(); ++i) + args[i] = m_arguments[i].v8Value(); + + v8::Local<v8::Object> result = SafeAllocation::newInstance(constructor, m_arguments.size(), args.get()); + if (!scope.success()) { + hadException = true; + return ScriptObject(); + } + + return ScriptObject(result); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptFunctionCall.h b/WebCore/bindings/v8/ScriptFunctionCall.h new file mode 100644 index 0000000..8365a4e --- /dev/null +++ b/WebCore/bindings/v8/ScriptFunctionCall.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 ScriptFunctionCall_h +#define ScriptFunctionCall_h + +#include "PlatformString.h" +#include "ScriptObject.h" + +#include <wtf/Vector.h> + +namespace WebCore { + class ScriptValue; + class ScriptState; + class ScriptString; + + class ScriptFunctionCall { + public: + ScriptFunctionCall(ScriptState* scriptState, const ScriptObject& thisObject, const String& name); + virtual ~ScriptFunctionCall() {}; + + void appendArgument(const ScriptObject&); + void appendArgument(const ScriptString&); + void appendArgument(const ScriptValue&); + void appendArgument(const String&); + void appendArgument(long long); + void appendArgument(unsigned int); + void appendArgument(int); + void appendArgument(bool); + ScriptValue call(bool& hadException, bool reportExceptions = true); + ScriptValue call(); + ScriptObject construct(bool& hadException, bool reportExceptions = true); + + protected: + ScriptState* m_scriptState; + ScriptObject m_thisObject; + String m_name; + Vector<ScriptValue> m_arguments; + }; + +} // namespace WebCore + +#endif // ScriptFunctionCall diff --git a/WebCore/bindings/v8/ScriptObject.cpp b/WebCore/bindings/v8/ScriptObject.cpp new file mode 100644 index 0000000..dd44acb --- /dev/null +++ b/WebCore/bindings/v8/ScriptObject.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "ScriptObject.h" + +#include "ScriptScope.h" +#include "ScriptState.h" + +#include "Document.h" +#include "Frame.h" +#include "V8Binding.h" +#include "V8Proxy.h" + +#include <v8.h> + +namespace WebCore { + +ScriptObject::ScriptObject(v8::Handle<v8::Object> v8Object) + : ScriptValue(v8Object) +{ +} + +v8::Local<v8::Object> ScriptObject::v8Object() const +{ + ASSERT(v8Value()->IsObject()); + return v8::Local<v8::Object>(v8::Object::Cast(*v8Value())); +} + +bool ScriptObject::set(ScriptState* scriptState, const String& name, const String& value) +{ + ScriptScope scope(scriptState); + v8Object()->Set(v8String(name), v8String(value)); + return scope.success(); +} + +bool ScriptObject::set(ScriptState* scriptState, const char* name, const ScriptObject& value) +{ + ScriptScope scope(scriptState); + v8Object()->Set(v8::String::New(name), value.v8Value()); + return scope.success(); +} + +bool ScriptObject::set(ScriptState* scriptState, const char* name, const String& value) +{ + ScriptScope scope(scriptState); + v8Object()->Set(v8::String::New(name), v8String(value)); + return scope.success(); +} + +bool ScriptObject::set(ScriptState* scriptState, const char* name, double value) +{ + ScriptScope scope(scriptState); + v8Object()->Set(v8::String::New(name), v8::Number::New(value)); + return scope.success(); +} + +bool ScriptObject::set(ScriptState* scriptState, const char* name, long long value) +{ + ScriptScope scope(scriptState); + v8Object()->Set(v8::String::New(name), v8::Number::New(value)); + return scope.success(); +} + +bool ScriptObject::set(ScriptState* scriptState, const char* name, int value) +{ + ScriptScope scope(scriptState); + v8Object()->Set(v8::String::New(name), v8::Number::New(value)); + return scope.success(); +} + +bool ScriptObject::set(ScriptState* scriptState, const char* name, bool value) +{ + ScriptScope scope(scriptState); + v8Object()->Set(v8::String::New(name), v8Boolean(value)); + return scope.success(); +} + +ScriptObject ScriptObject::createNew(ScriptState* scriptState) +{ + ScriptScope scope(scriptState); + return ScriptObject(v8::Object::New()); +} + +bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, const ScriptObject& value) +{ + ScriptScope scope(scriptState); + scope.global()->Set(v8::String::New(name), value.v8Value()); + return scope.success(); +} + +bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InspectorController* value) +{ + ScriptScope scope(scriptState); + scope.global()->Set(v8::String::New(name), V8Proxy::ToV8Object(V8ClassIndex::INSPECTORCONTROLLER, value)); + return scope.success(); +} + +bool ScriptGlobalObject::get(ScriptState* scriptState, const char* name, ScriptObject& value) +{ + ScriptScope scope(scriptState); + v8::Local<v8::Value> v8Value = scope.global()->Get(v8::String::New(name)); + if (v8Value.IsEmpty()) + return false; + + if (!v8Value->IsObject()) + return false; + + value = ScriptObject(v8::Handle<v8::Object>(v8::Object::Cast(*v8Value))); + return true; +} + +bool ScriptGlobalObject::remove(ScriptState* scriptState, const char* name) +{ + ScriptScope scope(scriptState); + return scope.global()->Delete(v8::String::New(name)); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptObject.h b/WebCore/bindings/v8/ScriptObject.h new file mode 100644 index 0000000..e5618ab --- /dev/null +++ b/WebCore/bindings/v8/ScriptObject.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 ScriptObject_h +#define ScriptObject_h + +#include "ScriptValue.h" + +#include <v8.h> + +namespace WebCore { + class InspectorController; + class ScriptState; + + class ScriptObject : public ScriptValue { + public: + ScriptObject(v8::Handle<v8::Object>); + ScriptObject() {} + virtual ~ScriptObject() {} + + v8::Local<v8::Object> v8Object() const; + + bool set(ScriptState*, const String& name, const String&); + bool set(ScriptState*, const char* name, const ScriptObject&); + bool set(ScriptState*, const char* name, const String&); + bool set(ScriptState*, const char* name, double); + bool set(ScriptState*, const char* name, long long); + bool set(ScriptState*, const char* name, int); + bool set(ScriptState*, const char* name, bool); + + static ScriptObject createNew(ScriptState*); + }; + + class ScriptGlobalObject { + public: + static bool set(ScriptState*, const char* name, const ScriptObject&); + static bool set(ScriptState*, const char* name, InspectorController*); + static bool get(ScriptState*, const char* name, ScriptObject&); + static bool remove(ScriptState*, const char* name); + private: + ScriptGlobalObject() { } + }; + +} + +#endif // ScriptObject_h diff --git a/WebCore/bindings/v8/ScriptObjectQuarantine.cpp b/WebCore/bindings/v8/ScriptObjectQuarantine.cpp new file mode 100644 index 0000000..8a7715e --- /dev/null +++ b/WebCore/bindings/v8/ScriptObjectQuarantine.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "ScriptObjectQuarantine.h" + +#include "Database.h" +#include "Document.h" +#include "DOMWindow.h" +#include "Frame.h" +#include "Page.h" +#include "ScriptObject.h" +#include "ScriptValue.h" + +#include "V8Binding.h" +#include "V8Proxy.h" + +#include <v8.h> + +namespace WebCore { + +ScriptValue quarantineValue(ScriptState* scriptState, const ScriptValue& value) +{ + return value; +} + +bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObject) +{ + ASSERT(database); + + // FIXME: Implement when Database V8 bindings are enabled + ASSERT_NOT_REACHED(); + quarantinedObject = ScriptObject(); + return false; +} + +bool getQuarantinedScriptObject(Frame* frame, Storage* storage, ScriptObject& quarantinedObject) +{ + ASSERT(frame); + ASSERT(storage); + + // FIXME: Implement when DOM Storage V8 bindings are enabled + ASSERT_NOT_REACHED(); + quarantinedObject = ScriptObject(); + return true; +} + +bool getQuarantinedScriptObject(Node* node, ScriptObject& quarantinedObject) +{ + ASSERT(node); + + v8::HandleScope handleScope; + v8::Local<v8::Context> context = V8Proxy::GetContext(node->document()->page()->mainFrame()); + v8::Context::Scope scope(context); + + v8::Handle<v8::Value> v8Node = V8Proxy::NodeToV8Object(node); + quarantinedObject = ScriptObject(v8::Local<v8::Object>(v8::Object::Cast(*v8Node))); + + return true; +} + +bool getQuarantinedScriptObject(DOMWindow* domWindow, ScriptObject& quarantinedObject) +{ + ASSERT(domWindow); + + v8::HandleScope handleScope; + v8::Local<v8::Context> context = V8Proxy::GetContext(domWindow->frame()); + v8::Context::Scope scope(context); + + v8::Handle<v8::Value> v8DomWindow = V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, domWindow); + quarantinedObject = ScriptObject(v8::Local<v8::Object>(v8::Object::Cast(*v8DomWindow))); + + return true; +} + + +} // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptObjectQuarantine.h b/WebCore/bindings/v8/ScriptObjectQuarantine.h new file mode 100644 index 0000000..3b7ccff --- /dev/null +++ b/WebCore/bindings/v8/ScriptObjectQuarantine.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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. + */ + +// ScriptObjectQuarantine is used in JSC for wrapping DOM objects of the page +// before they are passed to Inspector's front-end. The wrapping prevents +// malicious scripts from gaining privileges. For V8, we are currently just +// passing the object itself, without any wrapping. + +#ifndef ScriptObjectQuarantine_h +#define ScriptObjectQuarantine_h + +#include "ScriptState.h" + +namespace WebCore { + + class Database; + class DOMWindow; + class Frame; + class Node; + class ScriptObject; + class ScriptValue; + class Storage; + + ScriptValue quarantineValue(ScriptState*, const ScriptValue&); + + bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObject); + bool getQuarantinedScriptObject(Frame* frame, Storage* storage, ScriptObject& quarantinedObject); + bool getQuarantinedScriptObject(Node* node, ScriptObject& quarantinedObject); + bool getQuarantinedScriptObject(DOMWindow* domWindow, ScriptObject& quarantinedObject); + +} + +#endif // ScriptObjectQuarantine_h diff --git a/WebCore/bindings/v8/ScriptScope.cpp b/WebCore/bindings/v8/ScriptScope.cpp new file mode 100644 index 0000000..937f664 --- /dev/null +++ b/WebCore/bindings/v8/ScriptScope.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "ScriptScope.h" + +#include "ScriptState.h" + +#include "Document.h" +#include "Frame.h" +#include "V8Binding.h" +#include "V8Proxy.h" + +#include <v8.h> + +namespace WebCore { + +ScriptScope::ScriptScope(ScriptState* scriptState, bool reportExceptions) + : m_context(V8Proxy::GetContext(scriptState->frame())) + , m_scope(m_context) + , m_scriptState(scriptState) + , m_reportExceptions(reportExceptions) +{ + ASSERT(!m_context.IsEmpty()); +} + +bool ScriptScope::success() +{ + if (!m_exceptionCatcher.HasCaught()) + return true; + + v8::Local<v8::Message> message = m_exceptionCatcher.Message(); + if (m_reportExceptions) + m_scriptState->frame()->document()->reportException(toWebCoreString(message->Get()), message->GetLineNumber(), toWebCoreString(message->GetScriptResourceName())); + + m_exceptionCatcher.Reset(); + return false; +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptScope.h b/WebCore/bindings/v8/ScriptScope.h new file mode 100644 index 0000000..6fee458 --- /dev/null +++ b/WebCore/bindings/v8/ScriptScope.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 ScriptScope_h +#define ScriptScope_h + +#include <v8.h> + +namespace WebCore { + class ScriptState; + + class ScriptScope { + public: + ScriptScope(ScriptState* scriptState, bool reportExceptions = true); + bool success(); + + v8::Local<v8::Object> global() const { return m_context->Global(); } + + private: + v8::HandleScope m_handleScope; + v8::Local<v8::Context> m_context; + v8::Context::Scope m_scope; + v8::TryCatch m_exceptionCatcher; + ScriptState* m_scriptState; + bool m_reportExceptions; + }; + +} + +#endif // ScriptScope_h diff --git a/WebCore/bindings/v8/ScriptState.cpp b/WebCore/bindings/v8/ScriptState.cpp new file mode 100644 index 0000000..b9e240c --- /dev/null +++ b/WebCore/bindings/v8/ScriptState.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "ScriptState.h" + +#include "Frame.h" +#include "Node.h" +#include "Page.h" +#include "ScriptController.h" + +#include <wtf/Assertions.h> + +namespace WebCore { + +ScriptState::ScriptState(Frame* frame) + : m_frame(frame) +{ +} + +ScriptState* scriptStateFromNode(Node* node) +{ + // This should be never reached with V8 bindings (WebKit only uses it + // for non-JS bindings) + ASSERT_NOT_REACHED(); + return 0; +} + +ScriptState* scriptStateFromPage(Page* page) +{ + return page->mainFrame()->script()->state(); +} + +} diff --git a/WebCore/bindings/v8/ScriptState.h b/WebCore/bindings/v8/ScriptState.h index b5a9578..8fbcfa3 100644 --- a/WebCore/bindings/v8/ScriptState.h +++ b/WebCore/bindings/v8/ScriptState.h @@ -34,8 +34,15 @@ #include <v8.h> namespace WebCore { + class Node; + class Page; + class Frame; + class ScriptState { public: + ScriptState() { } + ScriptState(Frame* frame); + bool hadException() { return !m_exception.IsEmpty(); } void setException(v8::Local<v8::Value> exception) { @@ -43,9 +50,15 @@ namespace WebCore { } v8::Local<v8::Value> exception() { return m_exception; } + Frame* frame() const { return m_frame; } + private: v8::Local<v8::Value> m_exception; + Frame* m_frame; }; + + ScriptState* scriptStateFromNode(Node*); + ScriptState* scriptStateFromPage(Page*); } #endif // ScriptState_h diff --git a/WebCore/bindings/v8/ScriptString.h b/WebCore/bindings/v8/ScriptString.h index 66a575f..fe254a5 100644 --- a/WebCore/bindings/v8/ScriptString.h +++ b/WebCore/bindings/v8/ScriptString.h @@ -37,6 +37,7 @@ namespace WebCore { class ScriptString { public: + ScriptString() {} ScriptString(const String& s) : m_str(s) {} ScriptString(const char* s) : m_str(s) {} diff --git a/WebCore/bindings/v8/ScriptValue.h b/WebCore/bindings/v8/ScriptValue.h index bfb11c2..04e8819 100644 --- a/WebCore/bindings/v8/ScriptValue.h +++ b/WebCore/bindings/v8/ScriptValue.h @@ -91,6 +91,11 @@ public: return m_value == value.m_value; } + bool isEqual(ScriptState*, const ScriptValue& value) const + { + return m_value == value.m_value; + } + bool operator!=(const ScriptValue value) const { return !operator==(value); diff --git a/WebCore/bindings/v8/V8AbstractEventListener.cpp b/WebCore/bindings/v8/V8AbstractEventListener.cpp index 83ab856..462a729 100644 --- a/WebCore/bindings/v8/V8AbstractEventListener.cpp +++ b/WebCore/bindings/v8/V8AbstractEventListener.cpp @@ -39,8 +39,8 @@ namespace WebCore { -V8AbstractEventListener::V8AbstractEventListener(Frame* frame, bool isInline) - : m_isInline(isInline) +V8AbstractEventListener::V8AbstractEventListener(Frame* frame, bool isAttribute) + : m_isAttribute(isAttribute) , m_frame(frame) , m_lineNumber(0) , m_columnNumber(0) @@ -49,7 +49,7 @@ V8AbstractEventListener::V8AbstractEventListener(Frame* frame, bool isInline) return; // Get the position in the source if any. - if (m_isInline && m_frame->document()->tokenizer()) { + if (m_isAttribute && m_frame->document()->tokenizer()) { m_lineNumber = m_frame->document()->tokenizer()->lineNumber(); m_columnNumber = m_frame->document()->tokenizer()->columnNumber(); } @@ -57,27 +57,21 @@ V8AbstractEventListener::V8AbstractEventListener(Frame* frame, bool isInline) void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> context, Event* event, v8::Handle<v8::Value> jsEvent, bool isWindowEvent) { - // For compatibility, we store the event object as a property on the window called "event". Because this is the global namespace, we save away any - // existing "event" property, and then restore it after executing the javascript handler. + // We push the event being processed into the global object, so that it can be exposed by DOMWindow's bindings. v8::Local<v8::String> eventSymbol = v8::String::NewSymbol("event"); v8::Local<v8::Value> returnValue; { // Catch exceptions thrown in the event handler so they do not propagate to javascript code that caused the event to fire. - // Setting and getting the 'event' property on the global object can throw exceptions as well (for instance if accessors that - // throw exceptions are defined for 'event' using __defineGetter__ and __defineSetter__ on the global object). v8::TryCatch tryCatch; tryCatch.SetVerbose(true); // Save the old 'event' property so we can restore it later. - v8::Local<v8::Value> savedEvent = context->Global()->Get(eventSymbol); + v8::Local<v8::Value> savedEvent = context->Global()->GetHiddenValue(eventSymbol); tryCatch.Reset(); - // Make the event available in the window object. - // - // FIXME: This does not work as it does with jsc bindings if the window.event property is already set. We need to make sure that property - // access is intercepted correctly. - context->Global()->Set(eventSymbol, jsEvent); + // Make the event available in the global object, so DOMWindow can expose it. + context->Global()->SetHiddenValue(eventSymbol, jsEvent); tryCatch.Reset(); // Call the event handler. @@ -86,9 +80,9 @@ void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> context // Restore the old event. This must be done for all exit paths through this method. if (savedEvent.IsEmpty()) - context->Global()->Set(eventSymbol, v8::Undefined()); + context->Global()->SetHiddenValue(eventSymbol, v8::Undefined()); else - context->Global()->Set(eventSymbol, savedEvent); + context->Global()->SetHiddenValue(eventSymbol, savedEvent); tryCatch.Reset(); } @@ -102,7 +96,7 @@ void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> context // Prevent default action if the return value is false; // FIXME: Add example, and reference to bug entry. - if (m_isInline && returnValue->IsBoolean() && !returnValue->BooleanValue()) + if (m_isAttribute && returnValue->IsBoolean() && !returnValue->BooleanValue()) event->preventDefault(); } @@ -133,7 +127,7 @@ void V8AbstractEventListener::handleEvent(Event* event, bool isWindowEvent) invokeEventHandler(context, event, jsEvent, isWindowEvent); - Document::updateDocumentsRendering(); + Document::updateStyleForAllDocuments(); } void V8AbstractEventListener::disposeListenerObject() diff --git a/WebCore/bindings/v8/V8AbstractEventListener.h b/WebCore/bindings/v8/V8AbstractEventListener.h index 0c34a86..ed643db 100644 --- a/WebCore/bindings/v8/V8AbstractEventListener.h +++ b/WebCore/bindings/v8/V8AbstractEventListener.h @@ -69,7 +69,7 @@ namespace WebCore { v8::Persistent<v8::Object> m_listener; // Indicates if this is an HTML type listener. - bool m_isInline; + bool m_isAttribute; private: V8AbstractEventListener(Frame*, bool isInline); diff --git a/WebCore/bindings/v8/V8Collection.cpp b/WebCore/bindings/v8/V8Collection.cpp new file mode 100644 index 0000000..861f68a --- /dev/null +++ b/WebCore/bindings/v8/V8Collection.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2006, 2007, 2008, 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "V8Collection.h" + +#include "ExceptionCode.h" +#include "HTMLOptionElement.h" +#include "V8HTMLOptionElement.h" + +namespace WebCore { + +v8::Handle<v8::Value> toOptionsCollectionSetter(uint32_t index, v8::Handle<v8::Value> value, HTMLSelectElement* base) +{ + if (value->IsNull() || value->IsUndefined()) { + base->remove(index); + return value; + } + + ExceptionCode ec = 0; + + // Check that the value is an HTMLOptionElement. If not, throw a TYPE_MISMATCH_ERR DOMException. + if (!V8HTMLOptionElement::HasInstance(value)) { + V8Proxy::SetDOMException(TYPE_MISMATCH_ERR); + return value; + } + + HTMLOptionElement* element = V8Proxy::DOMWrapperToNode<HTMLOptionElement>(v8::Handle<v8::Object>::Cast(value)); + base->setOption(index, element, ec); + + V8Proxy::SetDOMException(ec); + return value; +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/V8Collection.h b/WebCore/bindings/v8/V8Collection.h index 247c108..1731f9c 100644 --- a/WebCore/bindings/v8/V8Collection.h +++ b/WebCore/bindings/v8/V8Collection.h @@ -31,6 +31,8 @@ #ifndef V8Collection_h #define V8Collection_h +#include "HTMLFormElement.h" +#include "HTMLSelectElement.h" #include "V8Binding.h" #include "V8Proxy.h" #include <v8.h> @@ -70,6 +72,15 @@ namespace WebCore { // A template of named property accessor of collections. template<class Collection, class ItemType> static v8::Handle<v8::Value> collectionNamedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { + v8::Handle<v8::Value> value = info.Holder()->GetRealNamedPropertyInPrototypeChain(name); + + if (!value.IsEmpty()) + return value; + + // Search local callback properties next to find IDL defined + // properties. + if (info.Holder()->HasRealNamedCallbackProperty(name)) + return notHandledByInterceptor(); return getNamedPropertyOfCollection<Collection, ItemType>(name, info.Holder(), info.Data()); } @@ -78,6 +89,15 @@ namespace WebCore { { ASSERT(V8Proxy::MaybeDOMWrapper(info.Holder())); ASSERT(V8Proxy::GetDOMWrapperType(info.Holder()) == V8ClassIndex::NODE); + v8::Handle<v8::Value> value = info.Holder()->GetRealNamedPropertyInPrototypeChain(name); + + if (!value.IsEmpty()) + return value; + + // Search local callback properties next to find IDL defined + // properties. + if (info.Holder()->HasRealNamedCallbackProperty(name)) + return notHandledByInterceptor(); Collection* collection = V8Proxy::DOMWrapperToNode<Collection>(info.Holder()); String propertyName = toWebCoreString(name); void* implementation = collection->namedItem(propertyName); @@ -188,6 +208,8 @@ namespace WebCore { desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionStringOrNullIndexedPropertyGetter<Collection>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>); } + v8::Handle<v8::Value> toOptionsCollectionSetter(uint32_t index, v8::Handle<v8::Value>, HTMLSelectElement*); + } // namespace WebCore #endif // V8Collection_h diff --git a/WebCore/bindings/v8/V8DOMMap.cpp b/WebCore/bindings/v8/V8DOMMap.cpp index 82d9e69..60ce32b 100644 --- a/WebCore/bindings/v8/V8DOMMap.cpp +++ b/WebCore/bindings/v8/V8DOMMap.cpp @@ -40,6 +40,7 @@ #include <wtf/StdLibExtras.h> #include <wtf/Threading.h> #include <wtf/ThreadSpecific.h> +#include <wtf/Vector.h> namespace WebCore { @@ -47,7 +48,7 @@ namespace WebCore { // // There are two kinds of DOM objects: // 1. DOM tree nodes, such as Document, HTMLElement, ... -// there classes implements TreeShared<T> interface; +// there classes implement TreeShared<T> interface; // 2. Non-node DOM objects, such as CSSRule, Location, etc. // these classes implement a ref-counted scheme. // @@ -103,23 +104,21 @@ static void weakSVGObjectWithContextCallback(v8::Persistent<v8::Value> v8Object, // The helper function will be scheduled by the GC thread to get called from the owning thread. static void derefDelayedObjectsInCurrentThread(void*); -// This should be called to remove all DOM objects associated with the current thread when it is tearing down. -static void removeAllDOMObjectsInCurrentThread(); - -// A map from a thread ID to thread's specific data. +// A list of all ThreadSpecific DOM Data objects. Traversed during GC to find a thread-specific map that +// contains the object - so we can schedule the object to be deleted on the thread which created it. class ThreadSpecificDOMData; -typedef WTF::HashMap<WTF::ThreadIdentifier, ThreadSpecificDOMData*> DOMThreadMap; -static DOMThreadMap& domThreadMap() +typedef WTF::Vector<ThreadSpecificDOMData*> DOMDataList; +static DOMDataList& domDataList() { - DEFINE_STATIC_LOCAL(DOMThreadMap, staticDOMThreadMap, ()); - return staticDOMThreadMap; + DEFINE_STATIC_LOCAL(DOMDataList, staticDOMDataList, ()); + return staticDOMDataList; } -// Mutex to protect against concurrent access of domThreadMap. -static WTF::Mutex& domThreadMapMutex() +// Mutex to protect against concurrent access of DOMDataList. +static WTF::Mutex& domDataListMutex() { - DEFINE_STATIC_LOCAL(WTF::Mutex, staticDOMThreadMapMutex, ()); - return staticDOMThreadMapMutex; + DEFINE_STATIC_LOCAL(WTF::Mutex, staticDOMDataListMutex, ()); + return staticDOMDataListMutex; } class ThreadSpecificDOMData : Noncopyable { @@ -161,14 +160,14 @@ public: , m_delayedProcessingScheduled(false) , m_isMainThread(WTF::isMainThread()) { - WTF::MutexLocker locker(domThreadMapMutex()); - domThreadMap().set(WTF::currentThread(), this); + WTF::MutexLocker locker(domDataListMutex()); + domDataList().append(this); } virtual ~ThreadSpecificDOMData() { - WTF::MutexLocker locker(domThreadMapMutex()); - domThreadMap().remove(WTF::currentThread()); + WTF::MutexLocker locker(domDataListMutex()); + domDataList().remove(domDataList().find(this)); } void* getDOMWrapperMap(DOMWrapperMapType type) @@ -241,8 +240,6 @@ public: // We assume that all child threads running V8 instances are created by WTF. virtual ~NonMainThreadSpecificDOMData() { - removeAllDOMObjectsInCurrentThread(); - delete m_domNodeMap; delete m_domObjectMap; delete m_activeDomObjectMap; @@ -254,7 +251,8 @@ public: }; // This encapsulates thread-specific DOM data for the main thread. All the maps in it are static. -// This is because we are unable to rely on WTF::ThreadSpecificThreadExit to do the cleanup since the place that tears down the main thread can not call any WTF functions. +// This is because we are unable to rely on WTF::ThreadSpecificThreadExit to do the cleanup since +// the place that tears down the main thread can not call any WTF functions. class MainThreadSpecificDOMData : public ThreadSpecificDOMData { public: MainThreadSpecificDOMData() @@ -279,10 +277,8 @@ private: InternalDOMWrapperMap<Node> m_staticDomNodeMap; InternalDOMWrapperMap<void> m_staticDomObjectMap; InternalDOMWrapperMap<void> m_staticActiveDomObjectMap; -#if ENABLE(SVG) InternalDOMWrapperMap<SVGElementInstance> m_staticDomSvgElementInstanceMap; InternalDOMWrapperMap<void> m_staticDomSvgObjectWithContextMap; -#endif }; DEFINE_STATIC_LOCAL(WTF::ThreadSpecific<NonMainThreadSpecificDOMData>, threadSpecificDOMData, ()); @@ -386,16 +382,10 @@ static void weakSVGObjectWithContextCallback(v8::Persistent<v8::Value> v8Object, template<typename T> static void handleWeakObjectInOwningThread(ThreadSpecificDOMData::DOMWrapperMapType mapType, V8ClassIndex::V8WrapperType objectType, T* object) { - WTF::MutexLocker locker(domThreadMapMutex()); - for (typename DOMThreadMap::iterator iter(domThreadMap().begin()); iter != domThreadMap().end(); ++iter) { - WTF::ThreadIdentifier threadID = iter->first; - ThreadSpecificDOMData* threadData = iter->second; - - // Skip the current thread that is GC thread. - if (threadID == WTF::currentThread()) { - ASSERT(!static_cast<DOMWrapperMap<T>*>(threadData->getDOMWrapperMap(mapType))->contains(object)); - continue; - } + WTF::MutexLocker locker(domDataListMutex()); + DOMDataList& list = domDataList(); + for (size_t i = 0; i < list.size(); ++i) { + ThreadSpecificDOMData* threadData = list[i]; ThreadSpecificDOMData::InternalDOMWrapperMap<T>* domMap = static_cast<ThreadSpecificDOMData::InternalDOMWrapperMap<T>*>(threadData->getDOMWrapperMap(mapType)); if (domMap->contains(object)) { @@ -515,7 +505,7 @@ static void derefObject(V8ClassIndex::V8WrapperType type, void* domObject) static void derefDelayedObjects() { - WTF::MutexLocker locker(domThreadMapMutex()); + WTF::MutexLocker locker(domDataListMutex()); getThreadSpecificDOMData().setDelayedProcessingScheduled(false); @@ -574,7 +564,7 @@ static void removeAllDOMObjectsInCurrentThreadHelper() #endif } -static void removeAllDOMObjectsInCurrentThread() +void removeAllDOMObjectsInCurrentThread() { // Use the locker only if it has already been invoked before, as by worker thread. if (v8::Locker::IsActive()) { diff --git a/WebCore/bindings/v8/V8DOMMap.h b/WebCore/bindings/v8/V8DOMMap.h index 909fbcd..41dc2e04 100644 --- a/WebCore/bindings/v8/V8DOMMap.h +++ b/WebCore/bindings/v8/V8DOMMap.h @@ -31,8 +31,7 @@ #ifndef V8DOMMap_h #define V8DOMMap_h -#include "dom_wrapper_map.h" - +#include <wtf/HashMap.h> #include <v8.h> namespace WebCore { @@ -41,6 +40,61 @@ namespace WebCore { class SVGElementInstance; #endif + // A table of wrappers with weak pointers. + // This table allows us to avoid track wrapped objects for debugging + // and for ensuring that we don't double wrap the same object. + template<class KeyType, class ValueType> class WeakReferenceMap { + public: + WeakReferenceMap(v8::WeakReferenceCallback callback) : m_weakReferenceCallback(callback) { } + #ifndef NDEBUG + virtual ~WeakReferenceMap() + { + if (m_map.size() > 0) + fprintf(stderr, "Leak %d JS wrappers.\n", m_map.size()); + } + #endif + + // Get the JS wrapper object of an object. + virtual v8::Persistent<ValueType> get(KeyType* obj) + { + ValueType* wrapper = m_map.get(obj); + return wrapper ? v8::Persistent<ValueType>(wrapper) : v8::Persistent<ValueType>(); + } + + virtual void set(KeyType* obj, v8::Persistent<ValueType> wrapper) + { + ASSERT(!m_map.contains(obj)); + wrapper.MakeWeak(obj, m_weakReferenceCallback); + m_map.set(obj, *wrapper); + } + + virtual void forget(KeyType* obj) + { + ASSERT(obj); + ValueType* wrapper = m_map.take(obj); + if (!wrapper) + return; + + v8::Persistent<ValueType> handle(wrapper); + handle.Dispose(); + handle.Clear(); + } + + bool contains(KeyType* obj) { return m_map.contains(obj); } + + HashMap<KeyType*, ValueType*>& impl() { return m_map; } + + protected: + HashMap<KeyType*, ValueType*> m_map; + v8::WeakReferenceCallback m_weakReferenceCallback; + }; + + + template <class KeyType> class DOMWrapperMap : public WeakReferenceMap<KeyType, v8::Object> { + public: + DOMWrapperMap(v8::WeakReferenceCallback callback) : WeakReferenceMap<KeyType, v8::Object>(callback) { } + }; + // Callback when JS wrapper of active DOM object is dead. void weakActiveDOMObjectCallback(v8::Persistent<v8::Value> v8Object, void* domObject); @@ -53,6 +107,9 @@ namespace WebCore { // A map from a DOM object to its JS wrapper for DOM objects which can have pending activity. DOMWrapperMap<void>& getActiveDOMObjectMap(); + // This should be called to remove all DOM objects associated with the current thread when it is tearing down. + void removeAllDOMObjectsInCurrentThread(); + #if ENABLE(SVG) // A map for SVGElementInstances to its JS wrapper. DOMWrapperMap<SVGElementInstance>& getDOMSVGElementInstanceMap(); diff --git a/WebCore/bindings/v8/V8EventListenerList.cpp b/WebCore/bindings/v8/V8EventListenerList.cpp new file mode 100644 index 0000000..df60028 --- /dev/null +++ b/WebCore/bindings/v8/V8EventListenerList.cpp @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "V8EventListenerList.h" + +#include "V8CustomEventListener.h" + +namespace WebCore { + +V8EventListenerListIterator::V8EventListenerListIterator(V8EventListenerList* list) + : m_list(list) + , m_vectorIndex(0) + , m_iter(list->m_table.begin()) +{ +} + +V8EventListenerListIterator::V8EventListenerListIterator(V8EventListenerList* list, bool shouldSeekToEnd) + : m_list(list) + , m_vectorIndex(0) + , m_iter(list->m_table.begin()) +{ + if (shouldSeekToEnd) + seekToEnd(); +} + +V8EventListenerListIterator::~V8EventListenerListIterator() { } + +void V8EventListenerListIterator::operator++() +{ + if (m_iter != m_list->m_table.end()) { + Vector<V8EventListener*>* vector = m_iter->second; + if (m_vectorIndex + 1 < vector->size()) { + m_vectorIndex++; + return; + } + m_vectorIndex = 0; + ++m_iter; + } +} + +bool V8EventListenerListIterator::operator==(const V8EventListenerListIterator& other) +{ + return other.m_iter == m_iter && other.m_vectorIndex == m_vectorIndex && other.m_list == m_list; +} + +bool V8EventListenerListIterator::operator!=(const V8EventListenerListIterator& other) +{ + return !operator==(other); +} + +V8EventListener* V8EventListenerListIterator::operator*() +{ + if (m_iter != m_list->m_table.end()) { + Vector<V8EventListener*>* vector = m_iter->second; + if (m_vectorIndex < vector->size()) + return vector->at(m_vectorIndex); + } + return 0; +} + +void V8EventListenerListIterator::seekToEnd() +{ + m_iter = m_list->m_table.end(); + m_vectorIndex = 0; +} + + +V8EventListenerList::V8EventListenerList() +{ +} + +V8EventListenerList::~V8EventListenerList() +{ +} + +V8EventListenerListIterator V8EventListenerList::begin() +{ + return iterator(this); +} + +V8EventListenerListIterator V8EventListenerList::end() +{ + return iterator(this, true); +} + + +static int getKey(v8::Local<v8::Object> object) +{ + // 0 is a sentinel value for the HashMap key, so we map it to 1. + int hash = object->GetIdentityHash(); + if (!hash) + return 1; + return hash; +} + +void V8EventListenerList::add(V8EventListener* listener) +{ + ASSERT(v8::Context::InContext()); + v8::HandleScope handleScope; + + v8::Local<v8::Object> object = listener->getListenerObject(); + int key = getKey(object); + Vector<V8EventListener*>* vector = m_table.get(key); + if (!vector) { + vector = new Vector<V8EventListener*>(); + m_table.set(key, vector); + } + vector->append(listener); + m_reverseTable.set(listener, key); +} + +void V8EventListenerList::remove(V8EventListener* listener) +{ + if (m_reverseTable.contains(listener)) { + int key = m_reverseTable.get(listener); + Vector<V8EventListener*>* vector = m_table.get(key); + if (!vector) + return; + for (size_t j = 0; j < vector->size(); j++) { + if (vector->at(j) == listener) { + vector->remove(j); + if (!vector->size()) { + m_table.remove(key); + delete vector; + vector = 0; + } + m_reverseTable.remove(listener); + return; + } + } + } +} + +void V8EventListenerList::clear() +{ + m_table.clear(); + m_reverseTable.clear(); +} + +V8EventListener* V8EventListenerList::find(v8::Local<v8::Object> object, bool isAttribute) +{ + ASSERT(v8::Context::InContext()); + int key = getKey(object); + + Vector<V8EventListener*>* vector = m_table.get(key); + if (!vector) + return 0; + + for (size_t i = 0; i < vector->size(); i++) { + V8EventListener* element = vector->at(i); + if (isAttribute == element->isAttribute() && object == element->getListenerObject()) + return element; + } + return 0; +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/V8EventListenerList.h b/WebCore/bindings/v8/V8EventListenerList.h new file mode 100644 index 0000000..d7799b8 --- /dev/null +++ b/WebCore/bindings/v8/V8EventListenerList.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 V8EventListenerList_h +#define V8EventListenerList_h + +#include <v8.h> +#include <wtf/Vector.h> +#include <wtf/HashMap.h> + +namespace WebCore { + class V8EventListener; + class V8EventListenerListIterator; + + // This is a container for V8EventListener objects that uses the identity hash of the v8::Object to + // speed up lookups + class V8EventListenerList { + public: + // Because v8::Object identity hashes are not guaranteed to be unique, we unfortunately can't just map + // an int to V8EventListener. Instead we define a HashMap of int to Vector of V8EventListener + // called a ListenerMultiMap. + typedef Vector<V8EventListener*>* Values; + struct ValuesTraits : HashTraits<Values> { + static const bool needsDestruction = true; + }; + typedef HashMap<int, Values, DefaultHash<int>::Hash, HashTraits<int>, ValuesTraits> ListenerMultiMap; + + V8EventListenerList(); + ~V8EventListenerList(); + + friend class V8EventListenerListIterator; + typedef V8EventListenerListIterator iterator; + + iterator begin(); + iterator end(); + + void add(V8EventListener*); + void remove(V8EventListener*); + V8EventListener* find(v8::Local<v8::Object>, bool isAttribute); + void clear(); + size_t size() { return m_table.size(); } + + private: + ListenerMultiMap m_table; + + // we also keep a reverse mapping of V8EventListener to v8::Object identity hash, + // in order to speed up removal by V8EventListener + HashMap<V8EventListener*, int> m_reverseTable; + }; + + class V8EventListenerListIterator { + public: + ~V8EventListenerListIterator(); + void operator++(); + bool operator==(const V8EventListenerListIterator&); + bool operator!=(const V8EventListenerListIterator&); + V8EventListener* operator*(); + private: + friend class V8EventListenerList; + explicit V8EventListenerListIterator(V8EventListenerList*); + V8EventListenerListIterator(V8EventListenerList*, bool shouldSeekToEnd); + void seekToEnd(); + + V8EventListenerList* m_list; + V8EventListenerList::ListenerMultiMap::iterator m_iter; + size_t m_vectorIndex; + }; + +} // namespace WebCore + +#endif // V8EventListenerList_h diff --git a/WebCore/bindings/v8/V8LazyEventListener.cpp b/WebCore/bindings/v8/V8LazyEventListener.cpp index f53370d..f0e81de 100644 --- a/WebCore/bindings/v8/V8LazyEventListener.cpp +++ b/WebCore/bindings/v8/V8LazyEventListener.cpp @@ -37,10 +37,11 @@ namespace WebCore { -V8LazyEventListener::V8LazyEventListener(Frame *frame, const String& code, const String& functionName) +V8LazyEventListener::V8LazyEventListener(Frame *frame, const String& code, const String& functionName, bool isSVGEvent) : V8AbstractEventListener(frame, true) , m_code(code) , m_functionName(functionName) + , m_isSVGEvent(isSVGEvent) , m_compiled(false) , m_wrappedFunctionCompiled(false) { @@ -93,7 +94,10 @@ v8::Local<v8::Function> V8LazyEventListener::getListenerFunction() // See issue 944690. // // The ECMAScript spec says (very obliquely) that the parameter to an event handler is named "evt". - String code = "(function (evt) {\n"; + // + // Don't use new lines so that lines in the modified handler + // have the same numbers as in the original code. + String code = "(function (evt) {"; code.append(m_code); code.append("\n})"); @@ -133,6 +137,13 @@ v8::Local<v8::Value> V8LazyEventListener::callListenerFunction(v8::Handle<v8::Va return proxy->CallFunction(handlerFunction, receiver, 1, parameters); } + +static v8::Handle<v8::Value> V8LazyEventListenerToString(const v8::Arguments& args) +{ + return args.Callee()->GetHiddenValue(v8::String::New("toStringString")); +} + + v8::Local<v8::Function> V8LazyEventListener::getWrappedListenerFunction() { if (m_wrappedFunctionCompiled) { @@ -161,20 +172,19 @@ v8::Local<v8::Function> V8LazyEventListener::getWrappedListenerFunction() // See chrome/fast/forms/form-action.html // chrome/fast/forms/selected-index-value.html // base/fast/overflow/onscroll-layer-self-destruct.html - String code = "(function (evt) {\n" \ - " with (this.ownerDocument ? this.ownerDocument : {}) {\n" \ - " with (this.form ? this.form : {}) {\n" \ - " with (this) {\n" \ - " return (function(evt){\n"; + // + // Don't use new lines so that lines in the modified handler + // have the same numbers as in the original code. + String code = "(function (evt) {" \ + "with (this.ownerDocument ? this.ownerDocument : {}) {" \ + "with (this.form ? this.form : {}) {" \ + "with (this) {" \ + "return (function(evt){"; code.append(m_code); - code.append( "\n" \ - "}).call(this, evt);\n" \ - " }\n" \ - " }\n" \ - " }\n" \ - "})"); + // Insert '\n' otherwise //-style comments could break the handler. + code.append( "\n}).call(this, evt);}}}})"); v8::Handle<v8::String> codeExternalString = v8ExternalString(code); - v8::Handle<v8::Script> script = V8Proxy::CompileScript(codeExternalString, m_frame->document()->url(), m_lineNumber - 4); + v8::Handle<v8::Script> script = V8Proxy::CompileScript(codeExternalString, m_frame->document()->url(), m_lineNumber); if (!script.IsEmpty()) { V8Proxy* proxy = V8Proxy::retrieve(m_frame); ASSERT(proxy); @@ -183,6 +193,30 @@ v8::Local<v8::Function> V8LazyEventListener::getWrappedListenerFunction() ASSERT(value->IsFunction()); m_wrappedFunction = v8::Persistent<v8::Function>::New(v8::Local<v8::Function>::Cast(value)); + + // Change the toString function on the wrapper function to avoid it returning the source for the actual wrapper function. Instead + // it returns source for a clean wrapper function with the event argument wrapping the event source code. The reason for this + // is that some web sites uses toString on event functions and the evals the source returned (some times a RegExp is applied as + // well) for some other use. That fails miserably if the actual wrapper source is returned. + v8::Local<v8::FunctionTemplate> toStringTemplate = v8::FunctionTemplate::New(V8LazyEventListenerToString); + v8::Local<v8::Function> toStringFunction; + if (!toStringTemplate.IsEmpty()) + toStringFunction = toStringTemplate->GetFunction(); + if (!toStringFunction.IsEmpty()) { + String toStringResult = "function "; + toStringResult.append(m_functionName); + toStringResult.append("("); + if (m_isSVGEvent) + toStringResult.append("evt"); + else + toStringResult.append("event"); + toStringResult.append(") {\n "); + toStringResult.append(m_code); + toStringResult.append("\n}"); + toStringFunction->SetHiddenValue(v8::String::New("toStringString"), v8ExternalString(toStringResult)); + m_wrappedFunction->Set(v8::String::New("toString"), toStringFunction); + } + #ifndef NDEBUG V8Proxy::RegisterGlobalHandle(EVENT_LISTENER, this, m_wrappedFunction); #endif diff --git a/WebCore/bindings/v8/V8LazyEventListener.h b/WebCore/bindings/v8/V8LazyEventListener.h index 7c7be34..62d9342 100644 --- a/WebCore/bindings/v8/V8LazyEventListener.h +++ b/WebCore/bindings/v8/V8LazyEventListener.h @@ -45,23 +45,24 @@ namespace WebCore { // A V8LazyEventListener is always a HTML event handler. class V8LazyEventListener : public V8AbstractEventListener { public: - static PassRefPtr<V8LazyEventListener> create(Frame* frame, const String& code, const String& functionName) + static PassRefPtr<V8LazyEventListener> create(Frame* frame, const String& code, const String& functionName, bool isSVGEvent) { - return adoptRef(new V8LazyEventListener(frame, code, functionName)); + return adoptRef(new V8LazyEventListener(frame, code, functionName, isSVGEvent)); } - virtual bool isInline() const { return true; } - // For lazy event listener, the listener object is the same as its listener // function without additional scope chains. virtual v8::Local<v8::Object> getListenerObject() { return getWrappedListenerFunction(); } private: - V8LazyEventListener(Frame*, const String& code, const String& functionName); + V8LazyEventListener(Frame*, const String& code, const String& functionName, bool isSVGEvent); virtual ~V8LazyEventListener(); + virtual bool virtualisAttribute() const { return true; } + String m_code; String m_functionName; + bool m_isSVGEvent; bool m_compiled; // If the event listener is on a non-document dom node, we compile the function with some implicit scope chains before it. diff --git a/WebCore/bindings/v8/V8ObjectEventListener.h b/WebCore/bindings/v8/V8ObjectEventListener.h index 730b96c..501bdac 100644 --- a/WebCore/bindings/v8/V8ObjectEventListener.h +++ b/WebCore/bindings/v8/V8ObjectEventListener.h @@ -47,7 +47,7 @@ namespace WebCore { return adoptRef(new V8ObjectEventListener(frame, listener, isInline)); } - protected: + private: V8ObjectEventListener(Frame*, v8::Local<v8::Object> listener, bool isInline); virtual ~V8ObjectEventListener(); }; diff --git a/WebCore/bindings/v8/V8XMLHttpRequestUtilities.cpp b/WebCore/bindings/v8/V8Utilities.cpp index dfd5e45..395a8df 100644 --- a/WebCore/bindings/v8/V8XMLHttpRequestUtilities.cpp +++ b/WebCore/bindings/v8/V8Utilities.cpp @@ -29,7 +29,7 @@ */ #include "config.h" -#include "V8XMLHttpRequestUtilities.h" +#include "V8Utilities.h" #include <v8.h> @@ -37,28 +37,27 @@ #include "V8Proxy.h" #include <wtf/Assertions.h> +#include "Frame.h" namespace WebCore { // Use an array to hold dependents. It works like a ref-counted scheme. -// A value can be added more than once to the xmlHttpRequest object. -void createHiddenXHRDependency(v8::Local<v8::Object> xmlHttpRequest, v8::Local<v8::Value> value) +// A value can be added more than once to the DOM object. +void createHiddenDependency(v8::Local<v8::Object> object, v8::Local<v8::Value> value, int cacheIndex) { - ASSERT(V8Proxy::GetDOMWrapperType(xmlHttpRequest) == V8ClassIndex::XMLHTTPREQUEST || V8Proxy::GetDOMWrapperType(xmlHttpRequest) == V8ClassIndex::XMLHTTPREQUESTUPLOAD); - v8::Local<v8::Value> cache = xmlHttpRequest->GetInternalField(V8Custom::kXMLHttpRequestCacheIndex); + v8::Local<v8::Value> cache = object->GetInternalField(cacheIndex); if (cache->IsNull() || cache->IsUndefined()) { cache = v8::Array::New(); - xmlHttpRequest->SetInternalField(V8Custom::kXMLHttpRequestCacheIndex, cache); + object->SetInternalField(cacheIndex, cache); } v8::Local<v8::Array> cacheArray = v8::Local<v8::Array>::Cast(cache); cacheArray->Set(v8::Integer::New(cacheArray->Length()), value); } -void removeHiddenXHRDependency(v8::Local<v8::Object> xmlHttpRequest, v8::Local<v8::Value> value) +void removeHiddenDependency(v8::Local<v8::Object> object, v8::Local<v8::Value> value, int cacheIndex) { - ASSERT(V8Proxy::GetDOMWrapperType(xmlHttpRequest) == V8ClassIndex::XMLHTTPREQUEST || V8Proxy::GetDOMWrapperType(xmlHttpRequest) == V8ClassIndex::XMLHTTPREQUESTUPLOAD); - v8::Local<v8::Value> cache = xmlHttpRequest->GetInternalField(V8Custom::kXMLHttpRequestCacheIndex); + v8::Local<v8::Value> cache = object->GetInternalField(cacheIndex); ASSERT(cache->IsArray()); v8::Local<v8::Array> cacheArray = v8::Local<v8::Array>::Cast(cache); for (int i = cacheArray->Length() - 1; i >= 0; --i) { @@ -73,4 +72,35 @@ void removeHiddenXHRDependency(v8::Local<v8::Object> xmlHttpRequest, v8::Local<v ASSERT_NOT_REACHED(); } +bool processingUserGesture() +{ + Frame* frame = V8Proxy::retrieveFrameForEnteredContext(); + return frame && frame->script()->processingUserGesture(); +} + +bool shouldAllowNavigation(Frame* frame) +{ + Frame* callingFrame = V8Proxy::retrieveFrameForCallingContext(); + return callingFrame && callingFrame->loader()->shouldAllowNavigation(frame); +} + +KURL completeURL(const String& relativeURL) +{ + // For histoical reasons, we need to complete the URL using the dynamic frame. + Frame* frame = V8Proxy::retrieveFrameForEnteredContext(); + if (!frame) + return KURL(); + return frame->loader()->completeURL(relativeURL); +} + +void navigateIfAllowed(Frame* frame, const KURL& url, bool lockHistory, bool lockBackForwardList) +{ + Frame* callingFrame = V8Proxy::retrieveFrameForCallingContext(); + if (!callingFrame) + return; + + if (!protocolIsJavaScript(url) || ScriptController::isSafeScript(frame)) + frame->loader()->scheduleLocationChange(url.string(), callingFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, processingUserGesture()); +} + } // namespace WebCore diff --git a/WebCore/bindings/v8/V8Utilities.h b/WebCore/bindings/v8/V8Utilities.h new file mode 100644 index 0000000..5769910 --- /dev/null +++ b/WebCore/bindings/v8/V8Utilities.h @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2006, 2007, 2008, 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 V8Utilities_h +#define V8Utilities_h + +// FIXME: Remove once chromium dependencies on v8_utility.h are removed. +#define V8UTILITIES_DEFINED 1 + +#include <v8.h> + +namespace WebCore { + + class Frame; + class KURL; + class String; + + // Use an array to hold dependents. It works like a ref-counted scheme. A value can be added more than once to the DOM object. + void createHiddenDependency(v8::Local<v8::Object>, v8::Local<v8::Value>, int cacheIndex); + void removeHiddenDependency(v8::Local<v8::Object>, v8::Local<v8::Value>, int cacheIndex); + + bool processingUserGesture(); + bool shouldAllowNavigation(Frame*); + KURL completeURL(const String& relativeURL); + void navigateIfAllowed(Frame*, const KURL&, bool lockHistory, bool lockBackForwardList); + + class AllowAllocation { + public: + inline AllowAllocation() + { + m_previous = m_current; + m_current = true; + } + + inline ~AllowAllocation() + { + m_current = m_previous; + } + + static bool m_current; + + private: + bool m_previous; + }; + + class SafeAllocation { + public: + static inline v8::Local<v8::Object> newInstance(v8::Handle<v8::Function>); + static inline v8::Local<v8::Object> newInstance(v8::Handle<v8::ObjectTemplate>); + static inline v8::Local<v8::Object> newInstance(v8::Handle<v8::Function>, int argc, v8::Handle<v8::Value> argv[]); + + // FIXME: These NewInstance functions are here to ease upstreaming. Remove along with V8UTILITIES_DEFINED once chromium dependencies on v8_utility.h are removed. + static inline v8::Local<v8::Object> NewInstance(v8::Handle<v8::Function>); + static inline v8::Local<v8::Object> NewInstance(v8::Handle<v8::ObjectTemplate>); + static inline v8::Local<v8::Object> NewInstance(v8::Handle<v8::Function>, int argc, v8::Handle<v8::Value> argv[]); + }; + + v8::Local<v8::Object> SafeAllocation::newInstance(v8::Handle<v8::Function> function) + { + if (function.IsEmpty()) + return v8::Local<v8::Object>(); + AllowAllocation allow; + return function->NewInstance(); + } + + v8::Local<v8::Object> SafeAllocation::newInstance(v8::Handle<v8::ObjectTemplate> objectTemplate) + { + if (objectTemplate.IsEmpty()) + return v8::Local<v8::Object>(); + AllowAllocation allow; + return objectTemplate->NewInstance(); + } + + v8::Local<v8::Object> SafeAllocation::newInstance(v8::Handle<v8::Function> function, int argc, v8::Handle<v8::Value> argv[]) + { + if (function.IsEmpty()) + return v8::Local<v8::Object>(); + AllowAllocation allow; + return function->NewInstance(argc, argv); + } + + // FIXME: These NewInstance functions are here to ease upstreaming. Remove along with V8UTILITIES_DEFINED once chromium dependencies on v8_utility.h are removed. + v8::Local<v8::Object> SafeAllocation::NewInstance(v8::Handle<v8::Function> function) + { + return newInstance(function); + } + + v8::Local<v8::Object> SafeAllocation::NewInstance(v8::Handle<v8::ObjectTemplate> objectTemplate) + { + return newInstance(objectTemplate); + } + + v8::Local<v8::Object> SafeAllocation::NewInstance(v8::Handle<v8::Function> function, int argc, v8::Handle<v8::Value> argv[]) + { + return newInstance(function, argc, argv); + } + +} // namespace WebCore + +#endif // V8Utilities_h diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp index ba7a2c0..9bb48fb 100644 --- a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp +++ b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp @@ -40,7 +40,7 @@ namespace WebCore { V8WorkerContextEventListener::V8WorkerContextEventListener(WorkerContextExecutionProxy* proxy, v8::Local<v8::Object> listener, bool isInline) - : V8ObjectEventListener(0, listener, isInline) + : V8EventListener(0, listener, isInline) , m_proxy(proxy) { } @@ -54,7 +54,7 @@ V8WorkerContextEventListener::~V8WorkerContextEventListener() void V8WorkerContextEventListener::handleEvent(Event* event, bool isWindowEvent) { - // Is the EventListener disconnected from the frame? + // Is the EventListener disconnected? if (disconnected()) return; @@ -62,7 +62,6 @@ void V8WorkerContextEventListener::handleEvent(Event* event, bool isWindowEvent) // See issue 889829. RefPtr<V8AbstractEventListener> protect(this); - v8::Locker locker; v8::HandleScope handleScope; v8::Handle<v8::Context> context = m_proxy->GetContext(); @@ -81,10 +80,10 @@ void V8WorkerContextEventListener::handleEvent(Event* event, bool isWindowEvent) v8::Local<v8::Value> V8WorkerContextEventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event, bool isWindowEvent) { v8::Local<v8::Function> handlerFunction = getListenerFunction(); - if (handlerFunction.IsEmpty()) + v8::Local<v8::Object> receiver = getReceiverObject(event, isWindowEvent); + if (handlerFunction.IsEmpty() || receiver.IsEmpty()) return v8::Local<v8::Value>(); - v8::Local<v8::Object> receiver = getReceiverObject(event, isWindowEvent); v8::Handle<v8::Value> parameters[1] = { jsEvent }; v8::Local<v8::Value> result = handlerFunction->Call(receiver, 1, parameters); diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.h b/WebCore/bindings/v8/V8WorkerContextEventListener.h index 85dae41..8e56a73 100644 --- a/WebCore/bindings/v8/V8WorkerContextEventListener.h +++ b/WebCore/bindings/v8/V8WorkerContextEventListener.h @@ -33,7 +33,7 @@ #if ENABLE(WORKERS) -#include "V8ObjectEventListener.h" +#include "V8CustomEventListener.h" #include <v8.h> #include <wtf/PassRefPtr.h> @@ -42,7 +42,7 @@ namespace WebCore { class Event; class WorkerContextExecutionProxy; - class V8WorkerContextEventListener : public V8ObjectEventListener { + class V8WorkerContextEventListener : public V8EventListener { public: static PassRefPtr<V8WorkerContextEventListener> create(WorkerContextExecutionProxy* proxy, v8::Local<v8::Object> listener, bool isInline) { @@ -54,6 +54,7 @@ namespace WebCore { virtual void handleEvent(Event*, bool isWindowEvent); virtual bool disconnected() const { return !m_proxy; } + WorkerContextExecutionProxy* proxy() const { return m_proxy; } void disconnect() { m_proxy = 0; } private: diff --git a/WebCore/bindings/v8/V8WorkerContextObjectEventListener.cpp b/WebCore/bindings/v8/V8WorkerContextObjectEventListener.cpp new file mode 100644 index 0000000..bec25f1 --- /dev/null +++ b/WebCore/bindings/v8/V8WorkerContextObjectEventListener.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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(WORKERS) + +#include "V8WorkerContextObjectEventListener.h" + +#include "WorkerContextExecutionProxy.h" + +namespace WebCore { + +static void weakObjectEventListenerCallback(v8::Persistent<v8::Value>, void* parameter) +{ + V8WorkerContextObjectEventListener* listener = static_cast<V8WorkerContextObjectEventListener*>(parameter); + + // Remove the wrapper + listener->proxy()->RemoveEventListener(listener); + + listener->disposeListenerObject(); +} + +V8WorkerContextObjectEventListener::V8WorkerContextObjectEventListener(WorkerContextExecutionProxy* proxy, v8::Local<v8::Object> listener, bool isInline) + : V8WorkerContextEventListener(proxy, listener, isInline) +{ + m_listener.MakeWeak(this, weakObjectEventListenerCallback); +} + +} // namespace WebCore + +#endif // WORKERS diff --git a/WebCore/bindings/v8/V8WorkerContextObjectEventListener.h b/WebCore/bindings/v8/V8WorkerContextObjectEventListener.h new file mode 100644 index 0000000..6471637 --- /dev/null +++ b/WebCore/bindings/v8/V8WorkerContextObjectEventListener.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 V8WorkerContextObjectEventListener_h +#define V8WorkerContextObjectEventListener_h + +#if ENABLE(WORKERS) + +#include "V8WorkerContextEventListener.h" +#include <v8.h> +#include <wtf/PassRefPtr.h> + +namespace WebCore { + + class WorkerContextExecutionProxy; + + class V8WorkerContextObjectEventListener : public V8WorkerContextEventListener { + public: + static PassRefPtr<V8WorkerContextObjectEventListener> create(WorkerContextExecutionProxy* proxy, v8::Local<v8::Object> listener, bool isInline) + { + return adoptRef(new V8WorkerContextObjectEventListener(proxy, listener, isInline)); + } + + private: + V8WorkerContextObjectEventListener(WorkerContextExecutionProxy*, v8::Local<v8::Object> listener, bool isInline); + }; + +} // namespace WebCore + +#endif // WORKERS + +#endif // V8WorkerContextObjectEventListener_h diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp index a46aa24..7af9536 100644 --- a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp +++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp @@ -39,6 +39,8 @@ #include "V8Proxy.h" #include "Event.h" #include "V8WorkerContextEventListener.h" +#include "V8WorkerContextObjectEventListener.h" +#include "Worker.h" #include "WorkerContext.h" #include "WorkerLocation.h" #include "WorkerNavigator.h" @@ -48,6 +50,33 @@ namespace WebCore { static bool isWorkersEnabled = false; +static void reportFatalErrorInV8(const char* location, const char* message) +{ + // FIXME: We temporarily deal with V8 internal error situations such as out-of-memory by crashing the worker. + CRASH(); +} + +static void handleConsoleMessage(v8::Handle<v8::Message> message, v8::Handle<v8::Value> data) +{ + WorkerContextExecutionProxy* proxy = WorkerContextExecutionProxy::retrieve(); + if (!proxy) + return; + + WorkerContext* workerContext = proxy->workerContext(); + if (!workerContext) + return; + + v8::Handle<v8::String> errorMessageString = message->Get(); + ASSERT(!errorMessageString.IsEmpty()); + String errorMessage = ToWebCoreString(errorMessageString); + + v8::Handle<v8::Value> resourceName = message->GetScriptResourceName(); + bool useURL = (resourceName.IsEmpty() || !resourceName->IsString()); + String resourceNameString = useURL ? workerContext->url() : ToWebCoreString(resourceName); + + workerContext->addMessage(ConsoleDestination, JSMessageSource, ErrorMessageLevel, errorMessage, message->GetLineNumber(), resourceNameString); +} + bool WorkerContextExecutionProxy::isWebWorkersEnabled() { return isWorkersEnabled; @@ -62,6 +91,7 @@ WorkerContextExecutionProxy::WorkerContextExecutionProxy(WorkerContext* workerCo : m_workerContext(workerContext) , m_recursion(0) { + initV8IfNeeded(); } WorkerContextExecutionProxy::~WorkerContextExecutionProxy() @@ -72,10 +102,13 @@ WorkerContextExecutionProxy::~WorkerContextExecutionProxy() void WorkerContextExecutionProxy::dispose() { // Disconnect all event listeners. - for (size_t listenerIndex = 0; listenerIndex < m_listeners.size(); ++listenerIndex) - m_listeners[listenerIndex]->disconnect(); + if (m_listeners.get()) + { + for (V8EventListenerList::iterator iterator(m_listeners->begin()); iterator != m_listeners->end(); ++iterator) + static_cast<V8WorkerContextEventListener*>(*iterator)->disconnect(); - m_listeners.clear(); + m_listeners->clear(); + } // Detach all events from their JS wrappers. for (size_t eventIndex = 0; eventIndex < m_events.size(); ++eventIndex) { @@ -90,17 +123,6 @@ void WorkerContextExecutionProxy::dispose() m_context.Dispose(); m_context.Clear(); } - - // Remove the wrapping between JS object and DOM object. This is because - // the worker context object is going to be disposed immediately when a - // worker thread is tearing down. We do not want to re-delete the real object - // when JS object is garbage collected. - v8::Locker locker; - v8::HandleScope scope; - v8::Persistent<v8::Object> wrapper = domObjectMap().get(m_workerContext); - if (!wrapper.IsEmpty()) - V8Proxy::SetDOMWrapper(wrapper, V8ClassIndex::INVALID_CLASS_INDEX, NULL); - domObjectMap().forget(m_workerContext); } WorkerContextExecutionProxy* WorkerContextExecutionProxy::retrieve() @@ -108,11 +130,30 @@ WorkerContextExecutionProxy* WorkerContextExecutionProxy::retrieve() v8::Handle<v8::Context> context = v8::Context::GetCurrent(); v8::Handle<v8::Object> global = context->Global(); global = V8Proxy::LookupDOMWrapper(V8ClassIndex::WORKERCONTEXT, global); - ASSERT(!global.IsEmpty()); + // Return 0 if the current executing context is not the worker context. + if (global.IsEmpty()) + return 0; WorkerContext* workerContext = V8Proxy::ToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, global); return workerContext->script()->proxy(); } +void WorkerContextExecutionProxy::initV8IfNeeded() +{ + static bool v8Initialized = false; + + if (v8Initialized) + return; + + // Tell V8 not to call the default OOM handler, binding code will handle it. + v8::V8::IgnoreOutOfMemoryException(); + v8::V8::SetFatalErrorHandler(reportFatalErrorInV8); + + // Set up the handler for V8 error message. + v8::V8::AddMessageListener(handleConsoleMessage); + + v8Initialized = true; +} + void WorkerContextExecutionProxy::initContextIfNeeded() { // Bail out if the context has already been initialized. @@ -121,7 +162,7 @@ void WorkerContextExecutionProxy::initContextIfNeeded() // Create a new environment v8::Persistent<v8::ObjectTemplate> globalTemplate; - m_context = v8::Context::New(NULL, globalTemplate); + m_context = v8::Context::New(0, globalTemplate); // Starting from now, use local context only. v8::Local<v8::Context> context = v8::Local<v8::Context>::New(m_context); @@ -132,7 +173,7 @@ void WorkerContextExecutionProxy::initContextIfNeeded() // Create a new JS object and use it as the prototype for the shadow global object. v8::Handle<v8::Function> workerContextConstructor = GetConstructor(V8ClassIndex::WORKERCONTEXT); - v8::Local<v8::Object> jsWorkerContext = SafeAllocation::NewInstance(workerContextConstructor); + v8::Local<v8::Object> jsWorkerContext = SafeAllocation::newInstance(workerContextConstructor); // Bail out if allocation failed. if (jsWorkerContext.IsEmpty()) { dispose(); @@ -143,10 +184,13 @@ void WorkerContextExecutionProxy::initContextIfNeeded() V8Proxy::SetDOMWrapper(jsWorkerContext, V8ClassIndex::ToInt(V8ClassIndex::WORKERCONTEXT), m_workerContext); V8Proxy::SetJSWrapperForDOMObject(m_workerContext, v8::Persistent<v8::Object>::New(jsWorkerContext)); + m_workerContext->ref(); // Insert the object instance as the prototype of the shadow object. v8::Handle<v8::Object> globalObject = m_context->Global(); globalObject->Set(implicitProtoString, jsWorkerContext); + + m_listeners.set(new V8EventListenerList()); } v8::Local<v8::Function> WorkerContextExecutionProxy::GetConstructor(V8ClassIndex::V8WrapperType type) @@ -173,6 +217,19 @@ v8::Handle<v8::Value> WorkerContextExecutionProxy::ToV8Object(V8ClassIndex::V8Wr if (type == V8ClassIndex::WORKERCONTEXT) return WorkerContextToV8Object(static_cast<WorkerContext*>(impl)); + if (type == V8ClassIndex::WORKER) { + v8::Persistent<v8::Object> result = getActiveDOMObjectMap().get(impl); + if (!result.IsEmpty()) + return result; + + v8::Local<v8::Object> object = toV8(type, type, impl); + if (!object.IsEmpty()) + static_cast<Worker*>(impl)->ref(); + result = v8::Persistent<v8::Object>::New(object); + V8Proxy::SetJSWrapperForDOMObject(impl, result); + return result; + } + // Non DOM node v8::Persistent<v8::Object> result = domObjectMap().get(impl); if (result.IsEmpty()) { @@ -222,7 +279,7 @@ v8::Handle<v8::Value> WorkerContextExecutionProxy::EventToV8Object(Event* event) return result; } -// A JS object of type EventTarget in the worker context can only be WorkerContext. +// A JS object of type EventTarget in the worker context can only be Worker or WorkerContext. v8::Handle<v8::Value> WorkerContextExecutionProxy::EventTargetToV8Object(EventTarget* target) { if (!target) @@ -232,6 +289,10 @@ v8::Handle<v8::Value> WorkerContextExecutionProxy::EventTargetToV8Object(EventTa if (workerContext) return WorkerContextToV8Object(workerContext); + Worker* worker = target->toWorker(); + if (worker) + return ToV8Object(V8ClassIndex::WORKER, worker); + ASSERT_NOT_REACHED(); return v8::Handle<v8::Value>(); } @@ -257,7 +318,7 @@ v8::Local<v8::Object> WorkerContextExecutionProxy::toV8(V8ClassIndex::V8WrapperT else function = V8Proxy::GetTemplate(descType)->GetFunction(); - v8::Local<v8::Object> instance = SafeAllocation::NewInstance(function); + v8::Local<v8::Object> instance = SafeAllocation::newInstance(function); if (!instance.IsEmpty()) { // Avoid setting the DOM wrapper for failed allocations. V8Proxy::SetDOMWrapper(instance, V8ClassIndex::ToInt(cptrType), impl); @@ -276,7 +337,6 @@ bool WorkerContextExecutionProxy::forgetV8EventObject(Event* event) v8::Local<v8::Value> WorkerContextExecutionProxy::evaluate(const String& script, const String& fileName, int baseLine) { - v8::Locker locker; v8::HandleScope hs; initContextIfNeeded(); @@ -319,34 +379,39 @@ v8::Local<v8::Value> WorkerContextExecutionProxy::runScript(v8::Handle<v8::Scrip return result; } -PassRefPtr<V8EventListener> WorkerContextExecutionProxy::FindOrCreateEventListener(v8::Local<v8::Value> object, bool isInline, bool findOnly) +PassRefPtr<V8EventListener> WorkerContextExecutionProxy::findOrCreateEventListenerHelper(v8::Local<v8::Value> object, bool isInline, bool findOnly, bool createObjectEventListener) { if (!object->IsObject()) return 0; - for (size_t index = 0; index < m_listeners.size(); ++index) { - V8EventListener* el = m_listeners[index]; - if (el->isInline() == isInline && el->getListenerObject() == object) - return el; - } + V8EventListener* listener = m_listeners->find(object->ToObject(), isInline); if (findOnly) - return NULL; + return listener; // Create a new one, and add to cache. - RefPtr<V8WorkerContextEventListener> listener = V8WorkerContextEventListener::create(this, v8::Local<v8::Object>::Cast(object), isInline); - m_listeners.append(listener.get()); + RefPtr<V8EventListener> newListener; + if (createObjectEventListener) + newListener = V8WorkerContextObjectEventListener::create(this, v8::Local<v8::Object>::Cast(object), isInline); + else + newListener = V8WorkerContextEventListener::create(this, v8::Local<v8::Object>::Cast(object), isInline); + m_listeners->add(newListener.get()); - return listener.release(); + return newListener.release(); +} + +PassRefPtr<V8EventListener> WorkerContextExecutionProxy::findOrCreateEventListener(v8::Local<v8::Value> object, bool isInline, bool findOnly) +{ + return findOrCreateEventListenerHelper(object, isInline, findOnly, false); +} + +PassRefPtr<V8EventListener> WorkerContextExecutionProxy::findOrCreateObjectEventListener(v8::Local<v8::Value> object, bool isInline, bool findOnly) +{ + return findOrCreateEventListenerHelper(object, isInline, findOnly, true); } void WorkerContextExecutionProxy::RemoveEventListener(V8EventListener* listener) { - for (size_t index = 0; index < m_listeners.size(); ++index) { - if (m_listeners[index] == listener) { - m_listeners.remove(index); - return; - } - } + m_listeners->remove(listener); } void WorkerContextExecutionProxy::trackEvent(Event* event) diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.h b/WebCore/bindings/v8/WorkerContextExecutionProxy.h index 3023666..dad191c 100644 --- a/WebCore/bindings/v8/WorkerContextExecutionProxy.h +++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.h @@ -35,7 +35,9 @@ #if ENABLE(WORKERS) #include <v8.h> +#include "V8EventListenerList.h" #include "V8Index.h" +#include <wtf/OwnPtr.h> #include <wtf/Vector.h> namespace WebCore { @@ -54,7 +56,6 @@ namespace WebCore { // FIXME: following function sshould have camelCased names once V8 code-generating script is migrated. v8::Local<v8::Context> GetContext() { return v8::Local<v8::Context>::New(m_context); } v8::Local<v8::Function> GetConstructor(V8ClassIndex::V8WrapperType); - PassRefPtr<V8EventListener> FindOrCreateEventListener(v8::Local<v8::Value> listener, bool isInline, bool findOnly); void RemoveEventListener(V8EventListener*); static v8::Handle<v8::Value> ToV8Object(V8ClassIndex::V8WrapperType type, void* impl); @@ -62,6 +63,10 @@ namespace WebCore { static v8::Handle<v8::Value> EventTargetToV8Object(EventTarget* target); static v8::Handle<v8::Value> WorkerContextToV8Object(WorkerContext* wc); + // Finds/creates event listener wrappers. + PassRefPtr<V8EventListener> findOrCreateEventListener(v8::Local<v8::Value> listener, bool isInline, bool findOnly); + PassRefPtr<V8EventListener> findOrCreateObjectEventListener(v8::Local<v8::Value> object, bool isInline, bool findOnly); + // Track the event so that we can detach it from the JS wrapper when a worker // terminates. This is needed because we need to be able to dispose these // events and releases references to their event targets: WorkerContext. @@ -73,7 +78,7 @@ namespace WebCore { // Returns WorkerContext object. WorkerContext* workerContext() { return m_workerContext; } - // Returns WorkerContextExecutionProxy object of the currently executing context. + // Returns WorkerContextExecutionProxy object of the currently executing context. 0 will be returned if the current executing context is not the worker context. static WorkerContextExecutionProxy* retrieve(); // Enables HTML5 worker support. @@ -81,8 +86,10 @@ namespace WebCore { static void setIsWebWorkersEnabled(bool); private: + void initV8IfNeeded(); void initContextIfNeeded(); void dispose(); + PassRefPtr<V8EventListener> findOrCreateEventListenerHelper(v8::Local<v8::Value> object, bool isInline, bool findOnly, bool createObjectEventListener); // Run an already compiled script. v8::Local<v8::Value> runScript(v8::Handle<v8::Script>); @@ -95,7 +102,7 @@ namespace WebCore { v8::Persistent<v8::Context> m_context; int m_recursion; - Vector<V8WorkerContextEventListener*> m_listeners; + OwnPtr<V8EventListenerList> m_listeners; Vector<Event*> m_events; }; diff --git a/WebCore/bindings/v8/WorkerScriptController.cpp b/WebCore/bindings/v8/WorkerScriptController.cpp index 85bee0a..b3ede11 100644 --- a/WebCore/bindings/v8/WorkerScriptController.cpp +++ b/WebCore/bindings/v8/WorkerScriptController.cpp @@ -39,6 +39,7 @@ #include "ScriptSourceCode.h" #include "ScriptValue.h" #include "DOMTimer.h" +#include "V8DOMMap.h" #include "WorkerContext.h" #include "WorkerContextExecutionProxy.h" #include "WorkerObjectProxy.h" @@ -55,6 +56,7 @@ WorkerScriptController::WorkerScriptController(WorkerContext* workerContext) WorkerScriptController::~WorkerScriptController() { + removeAllDOMObjectsInCurrentThread(); } ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode) @@ -66,7 +68,7 @@ ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode) } v8::Local<v8::Value> result = m_proxy->evaluate(sourceCode.source(), sourceCode.url().string(), sourceCode.startLine() - 1); - m_workerContext->thread()->workerObjectProxy()->reportPendingActivity(m_workerContext->hasPendingActivity()); + m_workerContext->thread()->workerObjectProxy().reportPendingActivity(m_workerContext->hasPendingActivity()); return ScriptValue(); } diff --git a/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp b/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp index c86f924..1ad0e7a 100644 --- a/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp +++ b/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp @@ -31,6 +31,7 @@ #include "config.h" #include "CSSStyleDeclaration.h" +#include "CSSParser.h" #include "CSSValue.h" #include "CSSPrimitiveValue.h" #include "EventTarget.h" @@ -42,6 +43,7 @@ #include <wtf/ASCIICType.h> #include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> +#include <wtf/StdLibExtras.h> #include <wtf/Vector.h> namespace WebCore { @@ -75,6 +77,13 @@ static bool hasCSSPropertyNamePrefix(const String& propertyName, const char* pre return false; } +class CSSPropertyInfo { +public: + int propID; + bool hadPixelOrPosPrefix; + bool wasFilter; +}; + // When getting properties on CSSStyleDeclarations, the name used from // Javascript and the actual name of the property are not the same, so // we have to do the following translation. The translation turns upper @@ -86,47 +95,61 @@ static bool hasCSSPropertyNamePrefix(const String& propertyName, const char* pre // Also, certain prefixes such as 'pos', 'css-' and 'pixel-' are stripped // and the hadPixelOrPosPrefix out parameter is used to indicate whether or // not the property name was prefixed with 'pos-' or 'pixel-'. -static String cssPropertyName(const String& propertyName, bool& hadPixelOrPosPrefix) +static CSSPropertyInfo* cssPropertyInfo(v8::Handle<v8::String>v8PropertyName) { - hadPixelOrPosPrefix = false; - - unsigned length = propertyName.length(); - 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; - hadPixelOrPosPrefix = true; - } else if (hasCSSPropertyNamePrefix(propertyName, "pos")) { - i += 3; - hadPixelOrPosPrefix = true; - } else if (hasCSSPropertyNamePrefix(propertyName, "webkit") - || hasCSSPropertyNamePrefix(propertyName, "khtml") - || hasCSSPropertyNamePrefix(propertyName, "apple")) - name.append('-'); - else if (WTF::isASCIIUpper(propertyName[0])) - return String(); - - name.append(WTF::toASCIILower(propertyName[i++])); - - for (; i < length; ++i) { - UChar c = propertyName[i]; - if (!WTF::isASCIIUpper(c)) - name.append(c); - else { + String propertyName = toWebCoreString(v8PropertyName); + typedef HashMap<String, CSSPropertyInfo*> CSSPropertyInfoMap; + DEFINE_STATIC_LOCAL(CSSPropertyInfoMap, map, ()); + CSSPropertyInfo* propInfo = map.get(propertyName); + if (!propInfo) { + unsigned length = propertyName.length(); + bool hadPixelOrPosPrefix = false; + if (!length) + return 0; + + Vector<UChar> name; + name.reserveCapacity(length); + + unsigned i = 0; + + if (hasCSSPropertyNamePrefix(propertyName, "css")) + i += 3; + else if (hasCSSPropertyNamePrefix(propertyName, "pixel")) { + i += 5; + hadPixelOrPosPrefix = true; + } else if (hasCSSPropertyNamePrefix(propertyName, "pos")) { + i += 3; + hadPixelOrPosPrefix = true; + } else if (hasCSSPropertyNamePrefix(propertyName, "webkit") + || hasCSSPropertyNamePrefix(propertyName, "khtml") + || hasCSSPropertyNamePrefix(propertyName, "apple")) name.append('-'); - name.append(WTF::toASCIILower(c)); + else if (WTF::isASCIIUpper(propertyName[0])) + return 0; + + name.append(WTF::toASCIILower(propertyName[i++])); + + for (; i < length; ++i) { + UChar c = propertyName[i]; + if (!WTF::isASCIIUpper(c)) + name.append(c); + else { + name.append('-'); + name.append(WTF::toASCIILower(c)); + } } - } - return String::adopt(name); + String propName = String::adopt(name); + int propertyID = cssPropertyID(propName); + if (propertyID) { + propInfo = new CSSPropertyInfo(); + propInfo->hadPixelOrPosPrefix = hadPixelOrPosPrefix; + propInfo->wasFilter = (propName == "filter"); + propInfo->propID = propertyID; + map.add(propertyName, propInfo); + } + } + return propInfo; } NAMED_PROPERTY_GETTER(CSSStyleDeclaration) @@ -137,30 +160,32 @@ NAMED_PROPERTY_GETTER(CSSStyleDeclaration) return notHandledByInterceptor(); // Search the style declaration. - CSSStyleDeclaration* imp = V8Proxy::ToNativeObject<CSSStyleDeclaration>(V8ClassIndex::CSSSTYLEDECLARATION, info.Holder()); - - bool hadPixelOrPosPrefix = false; - String propertyName = cssPropertyName(toWebCoreString(name), hadPixelOrPosPrefix); + CSSStyleDeclaration* imp = + V8Proxy::ToNativeObject<CSSStyleDeclaration>(V8ClassIndex::CSSSTYLEDECLARATION, info.Holder()); + CSSPropertyInfo* propInfo = cssPropertyInfo(name); // Do not handle non-property names. - if (!CSSStyleDeclaration::isPropertyName(propertyName)) + if (!propInfo) return notHandledByInterceptor(); - RefPtr<CSSValue> cssValue = imp->getPropertyCSSValue(propertyName); + RefPtr<CSSValue> cssValue = imp->getPropertyCSSValue(propInfo->propID); if (cssValue) { - if (hadPixelOrPosPrefix && cssValue->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE) - return v8::Number::New(static_cast<CSSPrimitiveValue*>(cssValue.get())->getFloatValue(CSSPrimitiveValue::CSS_PX)); + if (propInfo->hadPixelOrPosPrefix && + cssValue->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE) { + return v8::Number::New(static_cast<CSSPrimitiveValue*>( + cssValue.get())->getFloatValue(CSSPrimitiveValue::CSS_PX)); + } return v8StringOrNull(cssValue->cssText()); } - String result = imp->getPropertyValue(propertyName); + String result = imp->getPropertyValue(propInfo->propID); if (result.isNull()) result = ""; // convert null to empty string. // The 'filter' attribute is made undetectable in KJS/WebKit // to avoid confusion with IE's filter extension. - if (propertyName == "filter") + if (propInfo->wasFilter) return v8UndetectableString(result); return v8String(result); @@ -169,19 +194,25 @@ NAMED_PROPERTY_GETTER(CSSStyleDeclaration) NAMED_PROPERTY_SETTER(CSSStyleDeclaration) { INC_STATS("DOM.CSSStyleDeclaration.NamedPropertySetter"); - CSSStyleDeclaration* imp = V8Proxy::ToNativeObject<CSSStyleDeclaration>(V8ClassIndex::CSSSTYLEDECLARATION, info.Holder()); - - bool hadPixelOrPosPrefix = false; - String prop = cssPropertyName(toWebCoreString(name), hadPixelOrPosPrefix); - if (!CSSStyleDeclaration::isPropertyName(prop)) + CSSStyleDeclaration* imp = + V8Proxy::ToNativeObject<CSSStyleDeclaration>( + V8ClassIndex::CSSSTYLEDECLARATION, info.Holder()); + CSSPropertyInfo* propInfo = cssPropertyInfo(name); + if (!propInfo) return notHandledByInterceptor(); String propertyValue = valueToStringWithNullCheck(value); - if (hadPixelOrPosPrefix) + if (propInfo->hadPixelOrPosPrefix) propertyValue.append("px"); ExceptionCode ec = 0; - imp->setProperty(prop, propertyValue, ec); + int importantIndex = propertyValue.find("!important", 0, false); + bool important = false; + if (importantIndex != -1) { + important = true; + propertyValue = propertyValue.left(importantIndex - 1); + } + imp->setProperty(propInfo->propID, propertyValue, important, ec); if (ec) throwError(ec); diff --git a/WebCore/bindings/v8/custom/V8CanvasPixelArrayCustom.cpp b/WebCore/bindings/v8/custom/V8CanvasPixelArrayCustom.cpp new file mode 100644 index 0000000..28f6b59 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8CanvasPixelArrayCustom.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "CanvasPixelArray.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +namespace WebCore { + +// Get the specified value from the pixel buffer and return it wrapped as a JavaScript Number object to V8. Accesses outside the valid pixel buffer range return "undefined". +INDEXED_PROPERTY_GETTER(CanvasPixelArray) +{ + INC_STATS("DOM.CanvasPixelArray.IndexedPropertyGetter"); + CanvasPixelArray* pixelBuffer = V8Proxy::ToNativeObject<CanvasPixelArray>(V8ClassIndex::CANVASPIXELARRAY, info.Holder()); + + if ((index < 0) || (index >= pixelBuffer->length())) + return v8::Undefined(); + unsigned char result; + if (!pixelBuffer->get(index, result)) + return v8::Undefined(); + return v8::Number::New(result); +} + +// Set the specified value in the pixel buffer. Accesses outside the valid pixel buffer range are silently ignored. +INDEXED_PROPERTY_SETTER(CanvasPixelArray) +{ + INC_STATS("DOM.CanvasPixelArray.IndexedPropertySetter"); + CanvasPixelArray* pixelBuffer = V8Proxy::ToNativeObject<CanvasPixelArray>(V8ClassIndex::CANVASPIXELARRAY, info.Holder()); + + if ((index >= 0) && (index < pixelBuffer->length())) + pixelBuffer->set(index, value->NumberValue()); + return value; +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp b/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp index 0570e0e..26086ab 100644 --- a/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp +++ b/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp @@ -34,11 +34,15 @@ #include "CanvasGradient.h" #include "CanvasPattern.h" #include "CanvasStyle.h" +#include "ExceptionCode.h" +#include "FloatRect.h" #include "V8Binding.h" #include "V8CanvasGradient.h" #include "V8CanvasPattern.h" #include "V8CustomBinding.h" +#include "V8HTMLCanvasElement.h" +#include "V8HTMLImageElement.h" #include "V8Proxy.h" namespace WebCore { @@ -92,4 +96,330 @@ ACCESSOR_SETTER(CanvasRenderingContext2DFillStyle) impl->setFillStyle(toCanvasStyle(value)); } +// TODO: SetStrokeColor and SetFillColor are similar except function names, +// consolidate them into one. +CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetStrokeColor) +{ + INC_STATS("DOM.CanvasRenderingContext2D.setStrokeColor()"); + CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder()); + switch (args.Length()) { + case 1: + if (args[0]->IsString()) + context->setStrokeColor(ToWebCoreString(args[0])); + else + context->setStrokeColor(toFloat(args[0])); + break; + case 2: + if (args[0]->IsString()) + context->setStrokeColor(ToWebCoreString(args[0]), toFloat(args[1])); + else + context->setStrokeColor(toFloat(args[0]), toFloat(args[1])); + break; + case 4: + context->setStrokeColor(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3])); + break; + case 5: + context->setStrokeColor(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4])); + break; + default: + V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "setStrokeColor: Invalid number of arguments"); + break; + } + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetFillColor) +{ + INC_STATS("DOM.CanvasRenderingContext2D.setFillColor()"); + CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder()); + switch (args.Length()) { + case 1: + if (args[0]->IsString()) + context->setFillColor(ToWebCoreString(args[0])); + else + context->setFillColor(toFloat(args[0])); + break; + case 2: + if (args[0]->IsString()) + context->setFillColor(ToWebCoreString(args[0]), toFloat(args[1])); + else + context->setFillColor(toFloat(args[0]), toFloat(args[1])); + break; + case 4: + context->setFillColor(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3])); + break; + case 5: + context->setFillColor(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4])); + break; + default: + V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "setFillColor: Invalid number of arguments"); + break; + } + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(CanvasRenderingContext2DStrokeRect) +{ + INC_STATS("DOM.CanvasRenderingContext2D.strokeRect()"); + CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder()); + if (args.Length() == 5) + context->strokeRect(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4])); + else if (args.Length() == 4) + context->strokeRect(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3])); + else { + V8Proxy::SetDOMException(INDEX_SIZE_ERR); + return notHandledByInterceptor(); + } + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetShadow) +{ + INC_STATS("DOM.CanvasRenderingContext2D.setShadow()"); + CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder()); + + switch (args.Length()) { + case 3: + context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2])); + break; + case 4: + if (args[3]->IsString()) + context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), ToWebCoreString(args[3])); + else + context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3])); + break; + case 5: + if (args[3]->IsString()) + context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), ToWebCoreString(args[3]), toFloat(args[4])); + else + context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4])); + break; + case 7: + context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), toFloat(args[5]), toFloat(args[6])); + break; + case 8: + context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), toFloat(args[5]), toFloat(args[6]), toFloat(args[7])); + break; + default: + V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "setShadow: Invalid number of arguments"); + break; + } + + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(CanvasRenderingContext2DDrawImage) +{ + INC_STATS("DOM.CanvasRenderingContext2D.drawImage()"); + CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder()); + + v8::Handle<v8::Value> arg = args[0]; + + if (V8HTMLImageElement::HasInstance(arg)) { + ExceptionCode ec = 0; + HTMLImageElement* image_element = V8Proxy::DOMWrapperToNode<HTMLImageElement>(arg); + switch (args.Length()) { + case 3: + context->drawImage(image_element, toFloat(args[1]), toFloat(args[2])); + break; + case 5: + context->drawImage(image_element, toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), ec); + if (ec != 0) { + V8Proxy::SetDOMException(ec); + return notHandledByInterceptor(); + } + break; + case 9: + context->drawImage(image_element, + FloatRect(toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4])), + FloatRect(toFloat(args[5]), toFloat(args[6]), toFloat(args[7]), toFloat(args[8])), + ec); + if (ec != 0) { + V8Proxy::SetDOMException(ec); + return notHandledByInterceptor(); + } + break; + default: + V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "drawImage: Invalid number of arguments"); + return v8::Undefined(); + } + return v8::Undefined(); + } + + // HTMLCanvasElement + if (V8HTMLCanvasElement::HasInstance(arg)) { + ExceptionCode ec = 0; + HTMLCanvasElement* canvas_element = V8Proxy::DOMWrapperToNode<HTMLCanvasElement>(arg); + switch (args.Length()) { + case 3: + context->drawImage(canvas_element, toFloat(args[1]), toFloat(args[2])); + break; + case 5: + context->drawImage(canvas_element, toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), ec); + if (ec != 0) { + V8Proxy::SetDOMException(ec); + return notHandledByInterceptor(); + } + break; + case 9: + context->drawImage(canvas_element, + FloatRect(toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4])), + FloatRect(toFloat(args[5]), toFloat(args[6]), toFloat(args[7]), toFloat(args[8])), + ec); + if (ec != 0) { + V8Proxy::SetDOMException(ec); + return notHandledByInterceptor(); + } + break; + default: + V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "drawImage: Invalid number of arguments"); + return v8::Undefined(); + } + return v8::Undefined(); + } + + V8Proxy::SetDOMException(TYPE_MISMATCH_ERR); + return notHandledByInterceptor(); +} + +CALLBACK_FUNC_DECL(CanvasRenderingContext2DDrawImageFromRect) +{ + INC_STATS("DOM.CanvasRenderingContext2D.drawImageFromRect()"); + CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder()); + + v8::Handle<v8::Value> arg = args[0]; + + if (V8HTMLImageElement::HasInstance(arg)) { + HTMLImageElement* image_element = V8Proxy::DOMWrapperToNode<HTMLImageElement>(arg); + context->drawImageFromRect(image_element, toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), toFloat(args[5]), toFloat(args[6]), toFloat(args[7]), toFloat(args[8]), ToWebCoreString(args[9])); + } else + V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "drawImageFromRect: Invalid type of arguments"); + + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(CanvasRenderingContext2DCreatePattern) +{ + INC_STATS("DOM.CanvasRenderingContext2D.createPattern()"); + CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder()); + + v8::Handle<v8::Value> arg = args[0]; + + if (V8HTMLImageElement::HasInstance(arg)) { + HTMLImageElement* image_element = V8Proxy::DOMWrapperToNode<HTMLImageElement>(arg); + ExceptionCode ec = 0; + RefPtr<CanvasPattern> pattern = context->createPattern(image_element, valueToStringWithNullCheck(args[1]), ec); + if (ec != 0) { + V8Proxy::SetDOMException(ec); + return notHandledByInterceptor(); + } + return V8Proxy::ToV8Object(V8ClassIndex::CANVASPATTERN, pattern.get()); + } + + if (V8HTMLCanvasElement::HasInstance(arg)) { + HTMLCanvasElement* canvas_element = V8Proxy::DOMWrapperToNode<HTMLCanvasElement>(arg); + ExceptionCode ec = 0; + RefPtr<CanvasPattern> pattern = context->createPattern(canvas_element, valueToStringWithNullCheck(args[1]), ec); + if (ec != 0) { + V8Proxy::SetDOMException(ec); + return notHandledByInterceptor(); + } + return V8Proxy::ToV8Object(V8ClassIndex::CANVASPATTERN, pattern.get()); + } + + V8Proxy::SetDOMException(TYPE_MISMATCH_ERR); + return notHandledByInterceptor(); +} + +CALLBACK_FUNC_DECL(CanvasRenderingContext2DFillText) +{ + INC_STATS("DOM.CanvasRenderingContext2D.fillText()"); + + CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder()); + + // Two forms: + // * fillText(text, x, y) + // * fillText(text, x, y, maxWidth) + if (args.Length() < 3 || args.Length() > 4) { + V8Proxy::SetDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + + String text = ToWebCoreString(args[0]); + float x = toFloat(args[1]); + float y = toFloat(args[2]); + + if (args.Length() == 4) { + float maxWidth = toFloat(args[3]); + context->fillText(text, x, y, maxWidth); + } else + context->fillText(text, x, y); + + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(CanvasRenderingContext2DStrokeText) +{ + INC_STATS("DOM.CanvasRenderingContext2D.strokeText()"); + CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder()); + + // Two forms: + // * strokeText(text, x, y) + // * strokeText(text, x, y, maxWidth) + if (args.Length() < 3 || args.Length() > 4) { + V8Proxy::SetDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + + String text = ToWebCoreString(args[0]); + float x = toFloat(args[1]); + float y = toFloat(args[2]); + + if (args.Length() == 4) { + float maxWidth = toFloat(args[3]); + context->strokeText(text, x, y, maxWidth); + } else + context->strokeText(text, x, y); + + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(CanvasRenderingContext2DPutImageData) +{ + INC_STATS("DOM.CanvasRenderingContext2D.putImageData()"); + + // Two froms: + // * putImageData(ImageData, x, y) + // * putImageData(ImageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight) + if (args.Length() != 3 && args.Length() != 7) { + V8Proxy::SetDOMException(SYNTAX_ERR); + return notHandledByInterceptor(); + } + + CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder()); + + ImageData* imageData = 0; + + // Need to check that the argument is of the correct type, since + // ToNativeObject() expects it to be correct. If the argument was incorrect + // we leave it null, and putImageData() will throw the correct exception + // (TYPE_MISMATCH_ERR). + if (V8Proxy::IsWrapperOfType(args[0], V8ClassIndex::IMAGEDATA)) + imageData = V8Proxy::ToNativeObject<ImageData>(V8ClassIndex::IMAGEDATA, args[0]); + + ExceptionCode ec = 0; + + if (args.Length() == 7) + context->putImageData(imageData, toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), toFloat(args[5]), toFloat(args[6]), ec); + else + context->putImageData(imageData, toFloat(args[1]), toFloat(args[2]), ec); + + if (ec != 0) { + V8Proxy::SetDOMException(ec); + return notHandledByInterceptor(); + } + + return v8::Undefined(); +} + } // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8ClientRectListCustom.cpp b/WebCore/bindings/v8/custom/V8ClientRectListCustom.cpp new file mode 100644 index 0000000..e3f89b9 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8ClientRectListCustom.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "ClientRectList.h" + +#include "ClientRect.h" + +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" + +#include <wtf/RefPtr.h> + +namespace WebCore { + +INDEXED_PROPERTY_GETTER(ClientRectList) +{ + INC_STATS("DOM.ClientRectList.IndexedPropertyGetter"); + ClientRectList* imp = V8Proxy::ToNativeObject<ClientRectList>(V8ClassIndex::CLIENTRECTLIST, info.Holder()); + RefPtr<ClientRect> result = imp->item(index); + if (!result) + return notHandledByInterceptor(); + + return V8Proxy::ToV8Object(V8ClassIndex::CLIENTRECT, result.get()); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8CustomBinding.cpp b/WebCore/bindings/v8/custom/V8CustomBinding.cpp index 03361ea..037c729 100644 --- a/WebCore/bindings/v8/custom/V8CustomBinding.cpp +++ b/WebCore/bindings/v8/custom/V8CustomBinding.cpp @@ -37,6 +37,7 @@ #include "HTMLNames.h" #include "HTMLFrameElementBase.h" #include "CSSHelper.h" +#include "V8Proxy.h" namespace WebCore { diff --git a/WebCore/bindings/v8/custom/V8CustomEventListener.cpp b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp index 68c8328..bd9e307 100644 --- a/WebCore/bindings/v8/custom/V8CustomEventListener.cpp +++ b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp @@ -35,8 +35,8 @@ namespace WebCore { -V8EventListener::V8EventListener(Frame* frame, v8::Local<v8::Object> listener, bool isInline) - : V8AbstractEventListener(frame, isInline) +V8EventListener::V8EventListener(Frame* frame, v8::Local<v8::Object> listener, bool isAttribute) + : V8AbstractEventListener(frame, isAttribute) { m_listener = v8::Persistent<v8::Object>::New(listener); #ifndef NDEBUG diff --git a/WebCore/bindings/v8/custom/V8CustomEventListener.h b/WebCore/bindings/v8/custom/V8CustomEventListener.h index 1e613d0..20adf99 100644 --- a/WebCore/bindings/v8/custom/V8CustomEventListener.h +++ b/WebCore/bindings/v8/custom/V8CustomEventListener.h @@ -44,23 +44,22 @@ namespace WebCore { // that can handle the event. class V8EventListener : public V8AbstractEventListener { public: - static PassRefPtr<V8EventListener> create(Frame* frame, v8::Local<v8::Object> listener, bool isInline) + static PassRefPtr<V8EventListener> create(Frame* frame, v8::Local<v8::Object> listener, bool isAttribute) { - return adoptRef(new V8EventListener(frame, listener, isInline)); + return adoptRef(new V8EventListener(frame, listener, isAttribute)); } - virtual bool isInline() const { return m_isInline; } - // Detach the listener from its owner frame. void disconnectFrame() { m_frame = 0; } protected: - V8EventListener(Frame*, v8::Local<v8::Object> listener, bool isInline); + V8EventListener(Frame*, v8::Local<v8::Object> listener, bool isAttribute); virtual ~V8EventListener(); v8::Local<v8::Function> getListenerFunction(); private: virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*, bool isWindowEvent); + virtual bool virtualisAttribute() const { return m_isAttribute; } }; } // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp index 5333006..6233a1d 100644 --- a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp +++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp @@ -50,13 +50,13 @@ V8CustomSQLTransactionErrorCallback::~V8CustomSQLTransactionErrorCallback() m_callback.Dispose(); } -bool V8CustomSQLTransactionErrorCallback::handleEvent(SQLError* error) +void V8CustomSQLTransactionErrorCallback::handleEvent(SQLError* error) { v8::HandleScope handleScope; v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame.get()); if (context.IsEmpty()) - return true; + return; v8::Context::Scope scope(context); @@ -69,10 +69,6 @@ bool V8CustomSQLTransactionErrorCallback::handleEvent(SQLError* error) bool callbackReturnValue = false; invokeCallback(m_callback, 1, argv, callbackReturnValue); - - // FIXME: Eliminate return value once SQLTransactionErrorCallback is changed - // to match the spec. - return true; } } // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h index 13e8178..0387deb 100644 --- a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h +++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h @@ -51,7 +51,7 @@ public: } virtual ~V8CustomSQLTransactionErrorCallback(); - virtual bool handleEvent(SQLError*); + virtual void handleEvent(SQLError*); private: V8CustomSQLTransactionErrorCallback(v8::Local<v8::Object>, Frame*); diff --git a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp index d031a50..c13c3b2 100644 --- a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp +++ b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp @@ -35,24 +35,130 @@ #include "V8CustomBinding.h" #include "V8CustomEventListener.h" #include "V8Proxy.h" +#include "V8Utilities.h" +#include "Base64.h" +#include "ExceptionCode.h" #include "DOMTimer.h" #include "Frame.h" #include "FrameLoadRequest.h" #include "FrameView.h" +#include "HTMLCollection.h" #include "Page.h" #include "PlatformScreen.h" +#include "ScheduledAction.h" #include "ScriptSourceCode.h" #include "Settings.h" #include "WindowFeatures.h" - // Horizontal and vertical offset, from the parent content area, around newly // opened popups that don't specify a location. static const int popupTilePixels = 10; namespace WebCore { +v8::Handle<v8::Value> V8Custom::WindowSetTimeoutImpl(const v8::Arguments& args, bool singleShot) +{ + int argumentCount = args.Length(); + + if (argumentCount < 1) + return v8::Undefined(); + + DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder()); + + if (!imp->frame()) + return v8::Undefined(); + + if (!V8Proxy::CanAccessFrame(imp->frame(), true)) + return v8::Undefined(); + + ScriptExecutionContext* scriptContext = static_cast<ScriptExecutionContext*>(imp->frame()->document()); + + v8::Handle<v8::Value> function = args[0]; + + int32_t timeout = 0; + if (argumentCount >= 2) + timeout = args[1]->Int32Value(); + + int id; + if (function->IsString()) { + // Don't allow setting timeouts to run empty functions! + // (Bug 1009597) + WebCore::String functionString = toWebCoreString(function); + if (functionString.length() == 0) + return v8::Undefined(); + + id = DOMTimer::install(scriptContext, new ScheduledAction(functionString), timeout, singleShot); + } else if (function->IsFunction()) { + int paramCount = argumentCount >= 2 ? argumentCount - 2 : 0; + v8::Local<v8::Value>* params = 0; + if (paramCount > 0) { + params = new v8::Local<v8::Value>[paramCount]; + for (int i = 0; i < paramCount; i++) + // parameters must be globalized + params[i] = args[i+2]; + } + + // params is passed to action, and released in action's destructor + ScheduledAction* action = new ScheduledAction(v8::Handle<v8::Function>::Cast(function), paramCount, params); + + delete[] params; + + id = DOMTimer::install(scriptContext, action, timeout, singleShot); + } else + // FIXME(fqian): what's the right return value if failed. + return v8::Undefined(); + + return v8::Integer::New(id); +} + +static bool isAscii(const String& str) +{ + for (size_t i = 0; i < str.length(); i++) { + if (str[i] > 0xFF) + return false; + } + return true; +} + +static v8::Handle<v8::Value> convertBase64(const String& str, bool encode) +{ + if (!isAscii(str)) { + V8Proxy::SetDOMException(INVALID_CHARACTER_ERR); + return notHandledByInterceptor(); + } + + Vector<char> inputCharacters(str.length()); + for (size_t i = 0; i < str.length(); i++) + inputCharacters[i] = static_cast<char>(str[i]); + Vector<char> outputCharacters; + + if (encode) + base64Encode(inputCharacters, outputCharacters); + else { + if (!base64Decode(inputCharacters, outputCharacters)) + return throwError("Cannot decode base64", V8Proxy::GENERAL_ERROR); + } + + return v8String(String(outputCharacters.data(), outputCharacters.size())); +} + +ACCESSOR_GETTER(DOMWindowEvent) +{ + v8::Local<v8::String> eventSymbol = v8::String::NewSymbol("event"); + v8::Local<v8::Context> context = v8::Context::GetCurrent(); + v8::Handle<v8::Value> jsEvent = context->Global()->GetHiddenValue(eventSymbol); + if (jsEvent.IsEmpty()) + return v8::Undefined(); + return jsEvent; +} + +ACCESSOR_GETTER(DOMWindowCrypto) +{ + // FIXME: Implement me. + return v8::Undefined(); +} + ACCESSOR_SETTER(DOMWindowLocation) { v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This()); @@ -103,7 +209,7 @@ CALLBACK_FUNC_DECL(DOMWindowAddEventListener) if (!doc) return v8::Undefined(); - // TODO: Check if there is not enough arguments + // FIXME: Check if there is not enough arguments V8Proxy* proxy = V8Proxy::retrieve(imp->frame()); if (!proxy) return v8::Undefined(); @@ -113,7 +219,7 @@ CALLBACK_FUNC_DECL(DOMWindowAddEventListener) if (listener) { String eventType = toWebCoreString(args[0]); bool useCapture = args[2]->BooleanValue(); - doc->addWindowEventListener(eventType, listener, useCapture); + imp->addEventListener(eventType, listener, useCapture); } return v8::Undefined(); @@ -144,7 +250,7 @@ CALLBACK_FUNC_DECL(DOMWindowRemoveEventListener) if (listener) { String eventType = toWebCoreString(args[0]); bool useCapture = args[2]->BooleanValue(); - doc->removeWindowEventListener(eventType, listener.get(), useCapture); + imp->removeEventListener(eventType, listener.get(), useCapture); } return v8::Undefined(); @@ -155,39 +261,168 @@ CALLBACK_FUNC_DECL(DOMWindowPostMessage) INC_STATS("DOM.DOMWindow.postMessage()"); DOMWindow* window = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder()); - DOMWindow* source = V8Proxy::retrieveActiveFrame()->domWindow(); + DOMWindow* source = V8Proxy::retrieveFrameForCallingContext()->domWindow(); ASSERT(source->frame()); - String uri = source->frame()->loader()->url().string(); - v8::TryCatch tryCatch; String message = toWebCoreString(args[0]); MessagePort* port = 0; - String domain; + String targetOrigin; // This function has variable arguments and can either be: - // postMessage(message, port, domain); + // postMessage(message, port, targetOrigin); // or - // postMessage(message, domain); + // postMessage(message, targetOrigin); if (args.Length() > 2) { if (V8Proxy::IsWrapperOfType(args[1], V8ClassIndex::MESSAGEPORT)) port = V8Proxy::ToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, args[1]); - domain = valueToStringWithNullOrUndefinedCheck(args[2]); - } else - domain = valueToStringWithNullOrUndefinedCheck(args[1]); + targetOrigin = valueToStringWithNullOrUndefinedCheck(args[2]); + } else { + targetOrigin = valueToStringWithNullOrUndefinedCheck(args[1]); + } if (tryCatch.HasCaught()) return v8::Undefined(); ExceptionCode ec = 0; - window->postMessage(message, port, domain, source, ec); + window->postMessage(message, port, targetOrigin, source, ec); if (ec) V8Proxy::SetDOMException(ec); return v8::Undefined(); } +CALLBACK_FUNC_DECL(DOMWindowAtob) +{ + INC_STATS("DOM.DOMWindow.atob()"); + DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder()); + + if (!V8Proxy::CanAccessFrame(imp->frame(), true)) + return v8::Undefined(); + + if (args.Length() < 1) + return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR); + + if (args[0]->IsNull()) + return v8String(""); + + String str = toWebCoreString(args[0]); + return convertBase64(str, false); +} + +CALLBACK_FUNC_DECL(DOMWindowBtoa) +{ + INC_STATS("DOM.DOMWindow.btoa()"); + DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder()); + + if (!V8Proxy::CanAccessFrame(imp->frame(), true)) + return v8::Undefined(); + + if (args.Length() < 1) + return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR); + + if (args[0]->IsNull()) + return v8String(""); + + String str = toWebCoreString(args[0]); + return convertBase64(str, true); +} + +// FIXME(fqian): returning string is cheating, and we should +// fix this by calling toString function on the receiver. +// However, V8 implements toString in JavaScript, which requires +// switching context of receiver. I consider it is dangerous. +CALLBACK_FUNC_DECL(DOMWindowToString) +{ + INC_STATS("DOM.DOMWindow.toString()"); + return args.This()->ObjectProtoToString(); +} + +CALLBACK_FUNC_DECL(DOMWindowNOP) +{ + INC_STATS("DOM.DOMWindow.nop()"); + return v8::Undefined(); +} + +static String eventNameFromAttributeName(const String& name) +{ + ASSERT(name.startsWith("on")); + String eventType = name.substring(2); + + if (eventType.startsWith("w")) { + switch(eventType[eventType.length() - 1]) { + case 't': + eventType = "webkitAnimationStart"; + break; + case 'n': + eventType = "webkitAnimationIteration"; + break; + case 'd': + ASSERT(eventType.length() > 7); + if (eventType[7] == 'a') + eventType = "webkitAnimationEnd"; + else + eventType = "webkitTransitionEnd"; + break; + } + } + + return eventType; +} + +ACCESSOR_SETTER(DOMWindowEventHandler) +{ + v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This()); + if (holder.IsEmpty()) + return; + + DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder); + if (!imp->frame()) + return; + + Document* doc = imp->frame()->document(); + if (!doc) + return; + + String key = toWebCoreString(name); + String eventType = eventNameFromAttributeName(key); + + if (value->IsNull()) { + // Clear the event listener + imp->clearAttributeEventListener(eventType); + } else { + V8Proxy* proxy = V8Proxy::retrieve(imp->frame()); + if (!proxy) + return; + + RefPtr<EventListener> listener = + proxy->FindOrCreateV8EventListener(value, true); + if (listener) + imp->setAttributeEventListener(eventType, listener); + } +} + +ACCESSOR_GETTER(DOMWindowEventHandler) +{ + v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This()); + if (holder.IsEmpty()) + return v8::Undefined(); + + DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder); + if (!imp->frame()) + return v8::Undefined(); + + Document* doc = imp->frame()->document(); + if (!doc) + return v8::Undefined(); + + String key = toWebCoreString(name); + String eventType = eventNameFromAttributeName(key); + + EventListener* listener = imp->getAttributeEventListener(eventType); + return V8Proxy::EventListenerToV8Object(listener); +} static bool canShowModalDialogNow(const Frame* frame) { @@ -199,13 +434,13 @@ static bool canShowModalDialogNow(const Frame* frame) static bool allowPopUp() { - Frame* frame = V8Proxy::retrieveActiveFrame(); + Frame* frame = V8Proxy::retrieveFrameForEnteredContext(); ASSERT(frame); if (frame->script()->processingUserGesture()) return true; Settings* settings = frame->settings(); - return settings && settings->JavaScriptCanOpenWindowsAutomatically(); + return settings && settings->javaScriptCanOpenWindowsAutomatically(); } static HashMap<String, String> parseModalDialogFeatures(const String& featuresArg) @@ -240,17 +475,24 @@ static HashMap<String, String> parseModalDialogFeatures(const String& featuresAr } -static Frame* createWindow(Frame* openerFrame, +static Frame* createWindow(Frame* callingFrame, + Frame* enteredFrame, + Frame* openerFrame, const String& url, const String& frameName, const WindowFeatures& windowFeatures, v8::Local<v8::Value> dialogArgs) { - Frame* activeFrame = V8Proxy::retrieveActiveFrame(); + ASSERT(callingFrame); + ASSERT(enteredFrame); ResourceRequest request; - if (activeFrame) - request.setHTTPReferrer(activeFrame->loader()->outgoingReferrer()); + + // For whatever reason, Firefox uses the entered frame to determine + // the outgoingReferrer. We replicate that behavior here. + String referrer = enteredFrame->loader()->outgoingReferrer(); + request.setHTTPReferrer(referrer); + FrameLoader::addHTTPOriginIfNeeded(request, enteredFrame->loader()->outgoingOrigin()); FrameLoadRequest frameRequest(request, frameName); // FIXME: It's much better for client API if a new window starts with a URL, @@ -267,7 +509,7 @@ static Frame* createWindow(Frame* openerFrame, // frame name, in case the active frame is different from the opener frame, // and the name references a frame relative to the opener frame, for example // "_self" or "_parent". - Frame* newFrame = activeFrame->loader()->createWindow(openerFrame->loader(), frameRequest, windowFeatures, created); + Frame* newFrame = callingFrame->loader()->createWindow(openerFrame->loader(), frameRequest, windowFeatures, created); if (!newFrame) return 0; @@ -283,16 +525,15 @@ static Frame* createWindow(Frame* openerFrame, } } - if (!parseURL(url).startsWith("javascript:", false) - || ScriptController::isSafeScript(newFrame)) { + if (protocolIsJavaScript(url) || ScriptController::isSafeScript(newFrame)) { KURL completedUrl = - url.isEmpty() ? KURL("") : activeFrame->document()->completeURL(url); - bool userGesture = activeFrame->script()->processingUserGesture(); + url.isEmpty() ? KURL("") : completeURL(url); + bool userGesture = processingUserGesture(); if (created) - newFrame->loader()->changeLocation(completedUrl, activeFrame->loader()->outgoingReferrer(), false, false, userGesture); + newFrame->loader()->changeLocation(completedUrl, referrer, false, false, userGesture); else if (!url.isEmpty()) - newFrame->loader()->scheduleLocationChange(completedUrl.string(), activeFrame->loader()->outgoingReferrer(), false, userGesture); + newFrame->loader()->scheduleLocationChange(completedUrl.string(), referrer, false, userGesture); } return newFrame; @@ -310,6 +551,14 @@ CALLBACK_FUNC_DECL(DOMWindowShowModalDialog) if (!frame || !V8Proxy::CanAccessFrame(frame, true)) return v8::Undefined(); + Frame* callingFrame = V8Proxy::retrieveFrameForCallingContext(); + if (!callingFrame) + return v8::Undefined(); + + Frame* enteredFrame = V8Proxy::retrieveFrameForEnteredContext(); + if (!enteredFrame) + return v8::Undefined(); + if (!canShowModalDialogNow(frame) || !allowPopUp()) return v8::Undefined(); @@ -356,7 +605,7 @@ CALLBACK_FUNC_DECL(DOMWindowShowModalDialog) windowFeatures.locationBarVisible = false; windowFeatures.fullscreen = false; - Frame* dialogFrame = createWindow(frame, url, "", windowFeatures, dialogArgs); + Frame* dialogFrame = createWindow(callingFrame, enteredFrame, frame, url, "", windowFeatures, dialogArgs); if (!dialogFrame) return v8::Undefined(); @@ -387,16 +636,20 @@ CALLBACK_FUNC_DECL(DOMWindowOpen) DOMWindow* parent = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder()); Frame* frame = parent->frame(); - if (!V8Proxy::CanAccessFrame(frame, true)) - return v8::Undefined(); + if (!frame || !V8Proxy::CanAccessFrame(frame, true)) + return v8::Undefined(); - Frame* activeFrame = V8Proxy::retrieveActiveFrame(); - if (!activeFrame) - return v8::Undefined(); + Frame* callingFrame = V8Proxy::retrieveFrameForCallingContext(); + if (!callingFrame) + return v8::Undefined(); + + Frame* enteredFrame = V8Proxy::retrieveFrameForEnteredContext(); + if (!enteredFrame) + return v8::Undefined(); Page* page = frame->page(); if (!page) - return v8::Undefined(); + return v8::Undefined(); String urlString = valueToStringWithNullOrUndefinedCheck(args[0]); AtomicString frameName = (args[1]->IsUndefined() || args[1]->IsNull()) ? "_blank" : AtomicString(toWebCoreString(args[1])); @@ -421,18 +674,22 @@ CALLBACK_FUNC_DECL(DOMWindowOpen) topOrParent = true; } if (topOrParent) { - if (!activeFrame->loader()->shouldAllowNavigation(frame)) + if (!shouldAllowNavigation(frame)) return v8::Undefined(); String completedUrl; if (!urlString.isEmpty()) - completedUrl = activeFrame->document()->completeURL(urlString); + completedUrl = completeURL(urlString); if (!completedUrl.isEmpty() && - (!parseURL(urlString).startsWith("javascript:", false) - || ScriptController::isSafeScript(frame))) { - bool userGesture = activeFrame->script()->processingUserGesture(); - frame->loader()->scheduleLocationChange(completedUrl, activeFrame->loader()->outgoingReferrer(), false, userGesture); + (!protocolIsJavaScript(completedUrl) || ScriptController::isSafeScript(frame))) { + bool userGesture = processingUserGesture(); + + // For whatever reason, Firefox uses the entered frame to determine + // the outgoingReferrer. We replicate that behavior here. + String referrer = enteredFrame->loader()->outgoingReferrer(); + + frame->loader()->scheduleLocationChange(completedUrl, referrer, false, userGesture); } return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, frame->domWindow()); } @@ -489,7 +746,7 @@ CALLBACK_FUNC_DECL(DOMWindowOpen) windowFeatures.ySet = false; } - frame = createWindow(frame, urlString, frameName, windowFeatures, v8::Local<v8::Value>()); + frame = createWindow(callingFrame, enteredFrame, frame, urlString, frameName, windowFeatures, v8::Local<v8::Value>()); if (!frame) return v8::Undefined(); @@ -524,9 +781,6 @@ INDEXED_PROPERTY_GETTER(DOMWindow) NAMED_PROPERTY_GETTER(DOMWindow) { INC_STATS("DOM.DOMWindow.NamedPropertyGetter"); - // The key must be a string. - if (!name->IsString()) - return notHandledByInterceptor(); v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This()); if (holder.IsEmpty()) @@ -536,14 +790,13 @@ NAMED_PROPERTY_GETTER(DOMWindow) if (!window) return notHandledByInterceptor(); - String propName = toWebCoreString(name); - Frame* frame = window->frame(); // window is detached from a frame. if (!frame) return notHandledByInterceptor(); // Search sub-frames. + AtomicString propName = v8StringToAtomicWebCoreString(name); Frame* child = frame->tree()->child(propName); if (child) return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, child->domWindow()); @@ -553,66 +806,6 @@ NAMED_PROPERTY_GETTER(DOMWindow) if (!result.IsEmpty()) return result; - // Lazy initialization map keeps global properties that can be lazily - // initialized. The value is the code to instantiate the property. - // It must return the value of property after initialization. - static HashMap<String, String> lazyInitMap; - if (lazyInitMap.isEmpty()) { - // "new Image()" does not appear to be well-defined in a spec, but Safari, - // Opera, and Firefox all consider it to always create an HTML image - // element, regardless of the current doctype. - lazyInitMap.set("Image", - "function Image() { \ - return document.createElementNS( \ - 'http://www.w3.org/1999/xhtml', 'img'); \ - }; \ - Image"); - lazyInitMap.set("Option", - "function Option(text, value, defaultSelected, selected) { \ - var option = document.createElement('option'); \ - if (text == null) return option; \ - option.text = text; \ - if (value == null) return option; \ - option.value = value; \ - if (defaultSelected == null) return option; \ - option.defaultSelected = defaultSelected; \ - if (selected == null) return option; \ - option.selected = selected; \ - return option; \ - }; \ - Option"); - } - - String code = lazyInitMap.get(propName); - if (!code.isEmpty()) { - v8::Local<v8::Context> context = V8Proxy::GetContext(window->frame()); - // Bail out if we cannot get the context for the frame. - if (context.IsEmpty()) - return notHandledByInterceptor(); - - // switch to the target object's environment. - v8::Context::Scope scope(context); - - // Set the property name to undefined to make sure that the - // property exists. This is necessary because this getter - // might be called when evaluating 'var RangeException = value' - // to figure out if we have a property named 'RangeException' before - // we set RangeException to the new value. In that case, we will - // evaluate 'var RangeException = {}' and enter an infinite loop. - // Setting the property name to undefined on the global object - // ensures that we do not have to ask this getter to figure out - // that we have the property. - // - // TODO(ager): We probably should implement the Has method - // for the interceptor instead of using the default Has method - // that calls Get. - context->Global()->Set(v8String(propName), v8::Undefined()); - V8Proxy* proxy = V8Proxy::retrieve(window->frame()); - ASSERT(proxy); - - return proxy->evaluate(WebCore::ScriptSourceCode(code), 0); - } - // Search named items in the document. Document* doc = frame->document(); if (doc) { @@ -629,29 +822,20 @@ NAMED_PROPERTY_GETTER(DOMWindow) } -void V8Custom::WindowSetLocation(DOMWindow* window, const String& v) +void V8Custom::WindowSetLocation(DOMWindow* window, const String& relativeURL) { - if (!window->frame()) + Frame* frame = window->frame(); + if (!frame) return; - Frame* activeFrame = ScriptController::retrieveActiveFrame(); - if (!activeFrame) + if (!shouldAllowNavigation(frame)) return; - if (!activeFrame->loader()->shouldAllowNavigation(window->frame())) + KURL url = completeURL(relativeURL); + if (url.isNull()) return; - if (!parseURL(v).startsWith("javascript:", false) - || ScriptController::isSafeScript(window->frame())) { - String completedUrl = activeFrame->loader()->completeURL(v).string(); - - // FIXME: The JSC bindings pass !anyPageIsProcessingUserGesture() for - // the lockHistory parameter. We should probably do something similar. - - window->frame()->loader()->scheduleLocationChange(completedUrl, - activeFrame->loader()->outgoingReferrer(), false, false, - activeFrame->script()->processingUserGesture()); - } + navigateIfAllowed(frame, url, false, false); } @@ -695,4 +879,52 @@ CALLBACK_FUNC_DECL(DOMWindowClearInterval) return v8::Undefined(); } +NAMED_ACCESS_CHECK(DOMWindow) +{ + ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::DOMWINDOW); + v8::Handle<v8::Value> window = V8Proxy::LookupDOMWrapper(V8ClassIndex::DOMWINDOW, host); + if (window.IsEmpty()) + return false; // the frame is gone. + + DOMWindow* targetWindow = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, window); + + ASSERT(targetWindow); + + Frame* target = targetWindow->frame(); + if (!target) + return false; + + if (key->IsString()) { + String name = toWebCoreString(key); + + // Allow access of GET and HAS if index is a subframe. + if ((type == v8::ACCESS_GET || type == v8::ACCESS_HAS) && target->tree()->child(name)) + return true; + } + + return V8Proxy::CanAccessFrame(target, false); +} + +INDEXED_ACCESS_CHECK(DOMWindow) +{ + ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::DOMWINDOW); + v8::Handle<v8::Value> window = V8Proxy::LookupDOMWrapper(V8ClassIndex::DOMWINDOW, host); + if (window.IsEmpty()) + return false; + + DOMWindow* targetWindow = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, window); + + ASSERT(targetWindow); + + Frame* target = targetWindow->frame(); + if (!target) + return false; + + // Allow access of GET and HAS if index is a subframe. + if ((type == v8::ACCESS_GET || type == v8::ACCESS_HAS) && target->tree()->child(index)) + return true; + + return V8Proxy::CanAccessFrame(target, false); +} + } // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8DocumentLocationCustom.cpp b/WebCore/bindings/v8/custom/V8DocumentLocationCustom.cpp new file mode 100644 index 0000000..dfcacef --- /dev/null +++ b/WebCore/bindings/v8/custom/V8DocumentLocationCustom.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2000 Harri Porten (porten@kde.org) + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. + * Copyright (C) 2006 James G. Speth (speth@end.com) + * Copyright (C) 2006 Samuel Weinig (sam@webkit.org) + * Copyright (C) 2007, 2008, 2009 Google 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" +#include "V8CustomBinding.h" + +#include "DOMWindow.h" +#include "Frame.h" +#include "V8Binding.h" +#include "V8Document.h" +#include "V8Proxy.h" + +namespace WebCore { + +ACCESSOR_GETTER(DocumentLocation) +{ + Document* document = V8Proxy::DOMWrapperToNative<Document>(info.Holder()); + if (!document->frame()) + return v8::Null(); + + DOMWindow* window = document->frame()->domWindow(); + return V8Proxy::ToV8Object(V8ClassIndex::LOCATION, window->location()); +} + +ACCESSOR_SETTER(DocumentLocation) +{ + Document* document = V8Proxy::DOMWrapperToNative<Document>(info.Holder()); + if (!document->frame()) + return; + + DOMWindow* window = document->frame()->domWindow(); + // WindowSetLocation does security checks. // XXXMB- verify! + WindowSetLocation(window, toWebCoreString(value)); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8ElementCustom.cpp b/WebCore/bindings/v8/custom/V8ElementCustom.cpp index 131f401..64a9d3d 100644 --- a/WebCore/bindings/v8/custom/V8ElementCustom.cpp +++ b/WebCore/bindings/v8/custom/V8ElementCustom.cpp @@ -72,7 +72,7 @@ CALLBACK_FUNC_DECL(ElementSetAttributeNode) { INC_STATS("DOM.Element.setAttributeNode()"); if (!V8Attr::HasInstance(args[0])) - throwError(TYPE_MISMATCH_ERR); + return throwError(TYPE_MISMATCH_ERR); Attr* newAttr = V8Proxy::DOMWrapperToNode<Attr>(args[0]); Element* element = V8Proxy::DOMWrapperToNode<Element>(args.Holder()); @@ -147,21 +147,21 @@ ACCESSOR_SETTER(ElementEventHandler) // the document might be created using createDocument, // which does not have a frame, use the active frame if (!proxy) - proxy = V8Proxy::retrieve(V8Proxy::retrieveActiveFrame()); + proxy = V8Proxy::retrieve(V8Proxy::retrieveFrameForEnteredContext()); if (!proxy) return; if (RefPtr<EventListener> listener = proxy->FindOrCreateV8EventListener(value, true)) - node->setInlineEventListenerForType(eventType, listener); + node->setAttributeEventListener(eventType, listener); } else - node->removeInlineEventListenerForType(eventType); + node->clearAttributeEventListener(eventType); } ACCESSOR_GETTER(ElementEventHandler) { Node* node = V8Proxy::DOMWrapperToNode<Node>(info.Holder()); - EventListener* listener = node->inlineEventListenerForType(toEventType(name)); + EventListener* listener = node->getAttributeEventListener(toEventType(name)); return V8Proxy::EventListenerToV8Object(listener); } diff --git a/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp index 97a3b4f..1436a48 100644 --- a/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp +++ b/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp @@ -38,7 +38,7 @@ namespace WebCore { -static v8::Handle<v8::Value> getNamedItems(HTMLCollection* collection, String name) +static v8::Handle<v8::Value> getNamedItems(HTMLCollection* collection, AtomicString name) { Vector<RefPtr<Node> > namedItems; collection->namedItems(name, namedItems); @@ -85,7 +85,7 @@ NAMED_PROPERTY_GETTER(HTMLCollection) // Finally, search the DOM structure. HTMLCollection* imp = V8Proxy::ToNativeObject<HTMLCollection>(V8ClassIndex::HTMLCOLLECTION, info.Holder()); - return getNamedItems(imp, toWebCoreString(name)); + return getNamedItems(imp, v8StringToAtomicWebCoreString(name)); } CALLBACK_FUNC_DECL(HTMLCollectionItem) diff --git a/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp index 1d408b2..34bf89c 100644 --- a/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp +++ b/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp @@ -32,6 +32,7 @@ #include "HTMLDocument.h" #include "Frame.h" +#include "HTMLCollection.h" #include "HTMLIFrameElement.h" #include "HTMLNames.h" @@ -40,6 +41,7 @@ #include "V8Proxy.h" #include <wtf/RefPtr.h> +#include <wtf/StdLibExtras.h> namespace WebCore { @@ -48,8 +50,9 @@ NAMED_PROPERTY_DELETER(HTMLDocument) // Only handle document.all. Insert the marker object into the // shadow internal field to signal that document.all is no longer // shadowed. - String key = toWebCoreString(name); - if (key != "all") + AtomicString key = v8StringToAtomicWebCoreString(name); + DEFINE_STATIC_LOCAL(const AtomicString, all, ("all")); + if (key != all) return deletionNotHandledByInterceptor(); ASSERT(info.Holder()->InternalFieldCount() == kHTMLDocumentInternalFieldCount); @@ -61,12 +64,13 @@ NAMED_PROPERTY_DELETER(HTMLDocument) NAMED_PROPERTY_GETTER(HTMLDocument) { INC_STATS("DOM.HTMLDocument.NamedPropertyGetter"); - AtomicString key = toWebCoreString(name); + AtomicString key = v8StringToAtomicWebCoreString(name); // Special case for document.all. If the value in the shadow // internal field is not the marker object, then document.all has // been temporarily shadowed and we return the value. - if (key == "all") { + DEFINE_STATIC_LOCAL(const AtomicString, all, ("all")); + if (key == all) { ASSERT(info.Holder()->InternalFieldCount() == kHTMLDocumentInternalFieldCount); v8::Local<v8::Value> marker = info.Holder()->GetInternalField(kHTMLDocumentMarkerIndex); v8::Local<v8::Value> value = info.Holder()->GetInternalField(kHTMLDocumentShadowIndex); @@ -114,7 +118,7 @@ CALLBACK_FUNC_DECL(HTMLDocumentWrite) { INC_STATS("DOM.HTMLDocument.write()"); HTMLDocument* htmlDocument = V8Proxy::DOMWrapperToNode<HTMLDocument>(args.Holder()); - Frame* frame = V8Proxy::retrieveActiveFrame(); + Frame* frame = V8Proxy::retrieveFrameForCallingContext(); ASSERT(frame); htmlDocument->write(writeHelperGetString(args), frame->document()); return v8::Undefined(); @@ -124,7 +128,7 @@ CALLBACK_FUNC_DECL(HTMLDocumentWriteln) { INC_STATS("DOM.HTMLDocument.writeln()"); HTMLDocument* htmlDocument = V8Proxy::DOMWrapperToNode<HTMLDocument>(args.Holder()); - Frame* frame = V8Proxy::retrieveActiveFrame(); + Frame* frame = V8Proxy::retrieveFrameForCallingContext(); ASSERT(frame); htmlDocument->writeln(writeHelperGetString(args), frame->document()); return v8::Undefined(); @@ -164,7 +168,7 @@ CALLBACK_FUNC_DECL(HTMLDocumentOpen) } } - Frame* frame = V8Proxy::retrieveActiveFrame(); + Frame* frame = V8Proxy::retrieveFrameForCallingContext(); htmlDocument->open(frame->document()); // Return the document. return args.Holder(); diff --git a/WebCore/bindings/v8/custom/V8HTMLFormElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLFormElementCustom.cpp index 454bbc0..27ab7e3 100644 --- a/WebCore/bindings/v8/custom/V8HTMLFormElementCustom.cpp +++ b/WebCore/bindings/v8/custom/V8HTMLFormElementCustom.cpp @@ -31,6 +31,7 @@ #include "config.h" #include "HTMLFormElement.h" +#include "HTMLCollection.h" #include "V8Binding.h" #include "V8CustomBinding.h" #include "V8NamedNodesCollection.h" @@ -38,11 +39,23 @@ namespace WebCore { +INDEXED_PROPERTY_GETTER(HTMLFormElement) +{ + INC_STATS("DOM.HTMLFormElement.IndexedPropertyGetter"); + HTMLFormElement* form = V8Proxy::DOMWrapperToNode<HTMLFormElement>(info.Holder()); + + RefPtr<Node> formElement = form->elements()->item(index); + if (!formElement) + return notHandledByInterceptor(); + return V8Proxy::NodeToV8Object(formElement.get()); +} + + NAMED_PROPERTY_GETTER(HTMLFormElement) { INC_STATS("DOM.HTMLFormElement.NamedPropertyGetter"); HTMLFormElement* imp = V8Proxy::DOMWrapperToNode<HTMLFormElement>(info.Holder()); - String v = toWebCoreString(name); + AtomicString v = v8StringToAtomicWebCoreString(name); // Call getNamedElements twice, first time check if it has a value // and let HTMLFormElement update its cache. @@ -51,7 +64,7 @@ NAMED_PROPERTY_GETTER(HTMLFormElement) Vector<RefPtr<Node> > elements; imp->getNamedElements(v, elements); if (elements.isEmpty()) - return v8::Handle<v8::Value>(); + return notHandledByInterceptor(); } // Second call may return different results from the first call, @@ -66,5 +79,12 @@ NAMED_PROPERTY_GETTER(HTMLFormElement) NodeList* collection = new V8NamedNodesCollection(elements); return V8Proxy::ToV8Object(V8ClassIndex::NODELIST, collection); } + +CALLBACK_FUNC_DECL(HTMLFormElementSubmit) { + INC_STATS("DOM.HTMLFormElement.submit()"); + HTMLFormElement* form = V8Proxy::DOMWrapperToNative<HTMLFormElement>(args.Holder()); + form->submit(0, false, false); + return v8::Undefined(); +} } // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp index df08542..220af02 100644 --- a/WebCore/bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp +++ b/WebCore/bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp @@ -48,7 +48,7 @@ NAMED_PROPERTY_GETTER(HTMLFrameSetElement) { INC_STATS("DOM.HTMLFrameSetElement.NamedPropertyGetter"); HTMLFrameSetElement* imp = V8Proxy::DOMWrapperToNode<HTMLFrameSetElement>(info.Holder()); - Node* frameNode = imp->children()->namedItem(toWebCoreString(name)); + Node* frameNode = imp->children()->namedItem(v8StringToAtomicWebCoreString(name)); if (frameNode && frameNode->hasTagName(HTMLNames::frameTag)) { Document* doc = static_cast<HTMLFrameElement*>(frameNode)->contentDocument(); if (!doc) diff --git a/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp b/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp new file mode 100644 index 0000000..afcc29d --- /dev/null +++ b/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "HTMLImageElement.h" + +#include "Document.h" +#include "Frame.h" +#include "HTMLNames.h" + +#include "V8Binding.h" +#include "V8Proxy.h" + +#include <wtf/RefPtr.h> + +namespace WebCore { + +CALLBACK_FUNC_DECL(HTMLImageElementConstructor) +{ + INC_STATS("DOM.HTMLImageElement.Contructor"); + + if (!args.IsConstructCall()) + return throwError("DOM object constructor cannot be called as a function."); + + Document* document = V8Proxy::retrieveFrame()->document(); + if (!document) + return throwError("Image constructor associated document is unavailable", V8Proxy::REFERENCE_ERROR); + + // Make sure the document is added to the DOM Node map. Otherwise, the HTMLImageElement instance + // may end up being the only node in the map and get garbage-ccollected prematurely. + V8Proxy::NodeToV8Object(document); + + RefPtr<HTMLImageElement> image = new HTMLImageElement(HTMLNames::imgTag, V8Proxy::retrieveFrame()->document()); + if (args.Length() > 0) { + image->setWidth(toInt32(args[0])); + if (args.Length() > 1) + image->setHeight(toInt32(args[1])); + } + + V8Proxy::SetDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::NODE), image.get()); + image->ref(); + V8Proxy::SetJSWrapperForDOMNode(image.get(), v8::Persistent<v8::Object>::New(args.Holder())); + return args.Holder(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp b/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp new file mode 100644 index 0000000..93a9b68 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "HTMLOptionElement.h" + +#include "Document.h" +#include "Frame.h" +#include "HTMLNames.h" +#include "Text.h" + +#include "V8Binding.h" +#include "V8Proxy.h" + +#include <wtf/RefPtr.h> + +namespace WebCore { + +CALLBACK_FUNC_DECL(HTMLOptionElementConstructor) +{ + INC_STATS("DOM.HTMLOptionElement.Contructor"); + + if (!args.IsConstructCall()) + return throwError("DOM object constructor cannot be called as a function."); + + Document* document = V8Proxy::retrieveFrame()->document(); + if (!document) + return throwError("Option constructor associated document is unavailable", V8Proxy::REFERENCE_ERROR); + + RefPtr<HTMLOptionElement> option = new HTMLOptionElement(HTMLNames::optionTag, V8Proxy::retrieveFrame()->document()); + + ExceptionCode ec = 0; + RefPtr<Text> text = document->createTextNode(""); + if (args.Length() > 0) { + if (!args[0]->IsUndefined()) { + text->setData(toWebCoreString(args[0]), ec); + if (ec) + throwError(ec); + } + + option->appendChild(text.release(), ec); + if (ec) + throwError(ec); + + if (args.Length() > 1) { + if (!args[1]->IsUndefined()) + option->setValue(toWebCoreString(args[1])); + + if (args.Length() > 2) { + option->setDefaultSelected(args[2]->BooleanValue()); + if (args.Length() > 3) + option->setSelected(args[3]->BooleanValue()); + } + } + } + + V8Proxy::SetDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::NODE), option.get()); + option->ref(); + V8Proxy::SetJSWrapperForDOMNode(option.get(), v8::Persistent<v8::Object>::New(args.Holder())); + return args.Holder(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp index c8f7f6e..9f0d25e 100644 --- a/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp +++ b/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp @@ -32,10 +32,10 @@ #include "HTMLOptionsCollection.h" #include "HTMLOptionElement.h" -#include "HTMLSelectElement.h" #include "ExceptionCode.h" #include "V8Binding.h" +#include "V8Collection.h" #include "V8CustomBinding.h" #include "V8HTMLOptionElement.h" #include "V8HTMLSelectElementCustom.h" @@ -113,4 +113,24 @@ ACCESSOR_SETTER(HTMLOptionsCollectionLength) V8Proxy::SetDOMException(ec); } +INDEXED_PROPERTY_GETTER(HTMLOptionsCollection) +{ + INC_STATS("DOM.HTMLOptionsCollection.IndexedPropertyGetter"); + HTMLOptionsCollection* collection = V8Proxy::ToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, info.Holder()); + + RefPtr<Node> result = collection->item(index); + if (!result) + return notHandledByInterceptor(); + + return V8Proxy::NodeToV8Object(result.get()); +} + +INDEXED_PROPERTY_SETTER(HTMLOptionsCollection) +{ + INC_STATS("DOM.HTMLOptionsCollection.IndexedPropertySetter"); + HTMLOptionsCollection* collection = V8Proxy::ToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, info.Holder()); + HTMLSelectElement* base = static_cast<HTMLSelectElement*>(collection->base()); + return toOptionsCollectionSetter(index, value, base); +} + } // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8HTMLSelectElementCollectionCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLSelectElementCollectionCustom.cpp new file mode 100644 index 0000000..8b3b72a --- /dev/null +++ b/WebCore/bindings/v8/custom/V8HTMLSelectElementCollectionCustom.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "HTMLSelectElement.h" + +#include "HTMLOptionsCollection.h" +#include "V8Binding.h" +#include "V8Collection.h" +#include "V8CustomBinding.h" +#include "V8NamedNodesCollection.h" +#include "V8Proxy.h" + +namespace WebCore { + +NAMED_PROPERTY_GETTER(HTMLSelectElementCollection) +{ + INC_STATS("DOM.HTMLSelectElementCollection.NamedPropertySetter"); + HTMLSelectElement* select = V8Proxy::DOMWrapperToNode<HTMLSelectElement>(info.Holder()); + v8::Handle<v8::Value> value = info.Holder()->GetRealNamedPropertyInPrototypeChain(name); + + if (!value.IsEmpty()) + return value; + + // Search local callback properties next to find IDL defined properties. + if (info.Holder()->HasRealNamedCallbackProperty(name)) + return notHandledByInterceptor(); + + PassRefPtr<HTMLOptionsCollection> collection = select->options(); + + Vector<RefPtr<Node> > items; + collection->namedItems(v8StringToAtomicWebCoreString(name), items); + + if (!items.size()) + return notHandledByInterceptor(); + + if (items.size() == 1) + return V8Proxy::NodeToV8Object(items.at(0).get()); + + NodeList* list = new V8NamedNodesCollection(items); + return V8Proxy::ToV8Object(V8ClassIndex::NODELIST, list); +} + +INDEXED_PROPERTY_SETTER(HTMLSelectElementCollection) +{ + INC_STATS("DOM.HTMLSelectElementCollection.IndexedPropertySetter"); + HTMLSelectElement* select = V8Proxy::DOMWrapperToNode<HTMLSelectElement>(info.Holder()); + return toOptionsCollectionSetter(index, value, select); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8InspectorControllerCustom.cpp b/WebCore/bindings/v8/custom/V8InspectorControllerCustom.cpp index 387806f..a85c0d6 100644 --- a/WebCore/bindings/v8/custom/V8InspectorControllerCustom.cpp +++ b/WebCore/bindings/v8/custom/V8InspectorControllerCustom.cpp @@ -31,7 +31,17 @@ #include "config.h" #include "InspectorController.h" +#include "DOMWindow.h" +#include "Frame.h" +#include "FrameLoader.h" #include "ExceptionCode.h" +#include "InspectorResource.h" +#include "NotImplemented.h" +#include "Node.h" +#include "Range.h" +#include "Page.h" +#include "TextIterator.h" +#include "VisiblePosition.h" #include "V8Binding.h" #include "V8CustomBinding.h" @@ -39,22 +49,87 @@ namespace WebCore { -CALLBACK_FUNC_DECL(InspectorControllerDebuggerEnabled) +CALLBACK_FUNC_DECL(InspectorControllerHighlightDOMNode) { - INC_STATS("InspectorController.debuggerEnabled()"); - return v8::False(); + INC_STATS("InspectorController.highlightDOMNode()"); + + if (args.Length() < 1) + return v8::Undefined(); + + Node* node = V8Proxy::DOMWrapperToNode<Node>(args[0]); + if (!node) + return v8::Undefined(); + + InspectorController* inspectorController = V8Proxy::ToNativeObject<InspectorController>(V8ClassIndex::INSPECTORCONTROLLER, args.Holder()); + inspectorController->highlight(node); + + return v8::Undefined(); } -CALLBACK_FUNC_DECL(InspectorControllerPauseOnExceptions) +CALLBACK_FUNC_DECL(InspectorControllerGetResourceDocumentNode) { - INC_STATS("InspectorController.pauseOnExceptions()"); - return v8::False(); + INC_STATS("InspectorController.getResourceDocumentNode()"); + + if (args.Length() < 1) + return v8::Undefined(); + + if (!args[1]->IsNumber()) + return v8::Undefined(); + + unsigned identifier = args[1]->Int32Value(); + + InspectorController* inspectorController = V8Proxy::ToNativeObject<InspectorController>(V8ClassIndex::INSPECTORCONTROLLER, args.Holder()); + RefPtr<InspectorResource> resource = inspectorController->resources().get(identifier); + ASSERT(resource); + if (!resource) + return v8::Undefined(); + + Frame* frame = resource->frame(); + Document* document = frame->document(); + + if (document->isPluginDocument() || document->isImageDocument() || document->isMediaDocument()) + return v8::Undefined(); + + return V8Proxy::ToV8Object(V8ClassIndex::DOCUMENT, document); } -CALLBACK_FUNC_DECL(InspectorControllerProfilerEnabled) +CALLBACK_FUNC_DECL(InspectorControllerSearch) { - INC_STATS("InspectorController.profilerEnabled()"); - return v8::False(); + INC_STATS("InspectorController.search()"); + + if (args.Length() < 2) + return v8::Undefined(); + + Node* node = V8Proxy::DOMWrapperToNode<Node>(args[0]); + if (!node) + return v8::Undefined(); + + String target = toWebCoreStringWithNullCheck(args[1]); + if (target.isEmpty()) + return v8::Undefined(); + + v8::Local<v8::Array> result = v8::Array::New(); + RefPtr<Range> searchRange(rangeOfContents(node)); + + ExceptionCode ec = 0; + int index = 0; + do { + RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, false)); + if (resultRange->collapsed(ec)) + break; + + // A non-collapsed result range can in some funky whitespace cases still not + // advance the range's start position (4509328). Break to avoid infinite loop. + VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM); + if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM)) + break; + + result->Set(v8::Number::New(index++), V8Proxy::ToV8Object<Range>(V8ClassIndex::RANGE, resultRange.get())); + + setStart(searchRange.get(), newStart); + } while (true); + + return result; } #if ENABLE(DATABASE) @@ -66,6 +141,92 @@ CALLBACK_FUNC_DECL(InspectorControllerDatabaseTableNames) } #endif +CALLBACK_FUNC_DECL(InspectorControllerInspectedWindow) +{ + INC_STATS("InspectorController.inspectedWindow()"); + + InspectorController* inspectorController = V8Proxy::ToNativeObject<InspectorController>(V8ClassIndex::INSPECTORCONTROLLER, args.Holder()); + return V8Proxy::ToV8Object<DOMWindow>(V8ClassIndex::DOMWINDOW, inspectorController->inspectedPage()->mainFrame()->domWindow()); +} + +CALLBACK_FUNC_DECL(InspectorControllerSetting) +{ + INC_STATS("InspectorController.setting()"); + + if (args.Length() < 1) + return v8::Undefined(); + + String key = toWebCoreStringWithNullCheck(args[0]); + if (key.isEmpty()) + return v8::Undefined(); + + InspectorController* inspectorController = V8Proxy::ToNativeObject<InspectorController>(V8ClassIndex::INSPECTORCONTROLLER, args.Holder()); + const InspectorController::Setting& setting = inspectorController ->setting(key); + + switch (setting.type()) { + default: + case InspectorController::Setting::NoType: + return v8::Undefined(); + case InspectorController::Setting::StringType: + return v8String(setting.string()); + case InspectorController::Setting::DoubleType: + return v8::Number::New(setting.doubleValue()); + case InspectorController::Setting::IntegerType: + return v8::Number::New(setting.integerValue()); + case InspectorController::Setting::BooleanType: + return v8Boolean(setting.booleanValue()); + case InspectorController::Setting::StringVectorType: { + const Vector<String>& strings = setting.stringVector(); + v8::Local<v8::Array> stringsArray = v8::Array::New(strings.size()); + const unsigned length = strings.size(); + for (unsigned i = 0; i < length; ++i) + stringsArray->Set(v8::Number::New(i), v8String(strings[i])); + return stringsArray; + } + } +} + +CALLBACK_FUNC_DECL(InspectorControllerSetSetting) +{ + INC_STATS("InspectorController.setSetting()"); + if (args.Length() < 2) + return v8::Undefined(); + + String key = toWebCoreStringWithNullCheck(args[0]); + if (key.isEmpty()) + return v8::Undefined(); + + InspectorController::Setting setting; + + v8::Local<v8::Value> value = args[1]; + if (value->IsUndefined() || value->IsNull()) { + // Do nothing. The setting is already NoType. + ASSERT(setting.type() == InspectorController::Setting::NoType); + } else if (value->IsString()) + setting.set(toWebCoreStringWithNullCheck(value)); + else if (value->IsNumber()) + setting.set(value->NumberValue()); + else if (value->IsBoolean()) + setting.set(value->BooleanValue()); + else if (value->IsArray()) { + v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(value); + Vector<String> strings; + for (unsigned i = 0; i < v8Array->Length(); ++i) { + String item = toWebCoreString(v8Array->Get(v8::Integer::New(i))); + if (item.isEmpty()) + return v8::Undefined(); + strings.append(item); + } + setting.set(strings); + } else + return v8::Undefined(); + + InspectorController* inspectorController = V8Proxy::ToNativeObject<InspectorController>(V8ClassIndex::INSPECTORCONTROLLER, args.Holder()); + inspectorController->setSetting(key, setting); + + return v8::Undefined(); +} + CALLBACK_FUNC_DECL(InspectorControllerWrapCallback) { INC_STATS("InspectorController.wrapCallback()"); diff --git a/WebCore/bindings/v8/custom/V8LocationCustom.cpp b/WebCore/bindings/v8/custom/V8LocationCustom.cpp index 6dc2652..c5f3b1d 100644 --- a/WebCore/bindings/v8/custom/V8LocationCustom.cpp +++ b/WebCore/bindings/v8/custom/V8LocationCustom.cpp @@ -35,6 +35,7 @@ #include "V8CustomBinding.h" #include "V8CustomEventListener.h" #include "V8Location.h" +#include "V8Utilities.h" #include "V8Proxy.h" #include "PlatformString.h" @@ -51,27 +52,12 @@ namespace WebCore { // This class is not very JS-engine specific. If we can move a couple of // methods to the scriptController, we should be able to unify the code // between JSC and V8: -// retrieveActiveFrame() - in JSC, this needs an ExecState. +// toCallingFrame() - in JSC, this needs an ExecState. // isSafeScript() -// Since JSC and V8 have different mechanisms for getting at the ActiveFrame, +// Since JSC and V8 have different mechanisms for getting at the calling frame, // we're just making all these custom for now. The functionality is simple // and mirrors JSLocationCustom.cpp. -static void navigateIfAllowed(Frame* frame, const KURL& url, bool lockHistory, bool lockBackForwardList) -{ - if (url.isEmpty()) - return; - - Frame* activeFrame = ScriptController::retrieveActiveFrame(); - if (!activeFrame) - return; - - if (!url.protocolIs("javascript") || ScriptController::isSafeScript(frame)) { - bool userGesture = activeFrame->script()->processingUserGesture(); - frame->loader()->scheduleLocationChange(url.string(), activeFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, userGesture); - } -} - ACCESSOR_SETTER(LocationHash) { INC_STATS("DOM.Location.hash._set"); @@ -137,20 +123,19 @@ ACCESSOR_SETTER(LocationHref) INC_STATS("DOM.Location.href._set"); v8::Handle<v8::Object> holder = info.Holder(); Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); - String href = toWebCoreString(value); Frame* frame = imp->frame(); if (!frame) return; - Frame* activeFrame = ScriptController::retrieveActiveFrame(); - if (!activeFrame) + if (!shouldAllowNavigation(frame)) return; - if (!activeFrame->loader()->shouldAllowNavigation(frame)) + KURL url = completeURL(toWebCoreString(value)); + if (url.isNull()) return; - navigateIfAllowed(frame, activeFrame->loader()->completeURL(href), false, false); + navigateIfAllowed(frame, url, false, false); } ACCESSOR_SETTER(LocationPathname) @@ -285,18 +270,11 @@ CALLBACK_FUNC_DECL(LocationReload) Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); Frame* frame = imp->frame(); - if (!frame) - return v8::Undefined(); - - Frame* activeFrame = ScriptController::retrieveActiveFrame(); - if (!activeFrame) + if (!frame || !ScriptController::isSafeScript(frame)) return v8::Undefined(); - if (!ScriptController::isSafeScript(frame)) - return v8::Undefined(); - - bool userGesture = activeFrame->script()->processingUserGesture(); - frame->loader()->scheduleRefresh(userGesture); + if (!protocolIsJavaScript(frame->loader()->url())) + frame->loader()->scheduleRefresh(processingUserGesture()); return v8::Undefined(); } @@ -305,20 +283,19 @@ CALLBACK_FUNC_DECL(LocationReplace) INC_STATS("DOM.Location.replace"); v8::Handle<v8::Value> holder = args.Holder(); Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); - String url = toWebCoreString(args[0]); Frame* frame = imp->frame(); if (!frame) return v8::Undefined(); - Frame* activeFrame = ScriptController::retrieveActiveFrame(); - if (!activeFrame) + if (!shouldAllowNavigation(frame)) return v8::Undefined(); - if (!activeFrame->loader()->shouldAllowNavigation(frame)) + KURL url = completeURL(toWebCoreString(args[0])); + if (url.isNull()) return v8::Undefined(); - navigateIfAllowed(frame, activeFrame->loader()->completeURL(url), true, true); + navigateIfAllowed(frame, url, true, true); return v8::Undefined(); } @@ -327,20 +304,19 @@ CALLBACK_FUNC_DECL(LocationAssign) INC_STATS("DOM.Location.assign"); v8::Handle<v8::Value> holder = args.Holder(); Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder); - String url = toWebCoreString(args[0]); Frame* frame = imp->frame(); if (!frame) return v8::Undefined(); - Frame* activeFrame = ScriptController::retrieveActiveFrame(); - if (!activeFrame) + if (!shouldAllowNavigation(frame)) return v8::Undefined(); - if (!activeFrame->loader()->shouldAllowNavigation(frame)) + KURL url = completeURL(toWebCoreString(args[0])); + if (url.isNull()) return v8::Undefined(); - navigateIfAllowed(frame, activeFrame->loader()->completeURL(url), false, false); + navigateIfAllowed(frame, url, false, false); return v8::Undefined(); } diff --git a/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp b/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp new file mode 100644 index 0000000..fce04b6 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "ExceptionCode.h" +#include "MessagePort.h" +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8ObjectEventListener.h" +#include "V8Proxy.h" +#include "V8Utilities.h" + +namespace WebCore { + +ACCESSOR_GETTER(MessagePortOnmessage) +{ + INC_STATS("DOM.MessagePort.onmessage._get"); + MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, info.Holder()); + return V8Proxy::EventListenerToV8Object(messagePort->onmessage()); +} + +ACCESSOR_SETTER(MessagePortOnmessage) +{ + INC_STATS("DOM.MessagePort.onmessage._set"); + MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, info.Holder()); + if (value->IsNull()) { + if (messagePort->onmessage()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(messagePort->onmessage()); + removeHiddenDependency(info.Holder(), listener->getListenerObject(), V8Custom::kMessagePortRequestCacheIndex); + } + + // Clear the listener. + messagePort->setOnmessage(0); + + } else { + V8Proxy* proxy = V8Proxy::retrieve(messagePort->scriptExecutionContext()); + if (!proxy) + return; + + RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); + if (listener) { + messagePort->setOnmessage(listener); + createHiddenDependency(info.Holder(), value, V8Custom::kMessagePortRequestCacheIndex); + } + } +} + +ACCESSOR_GETTER(MessagePortOnclose) +{ + INC_STATS("DOM.MessagePort.onclose._get"); + MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, info.Holder()); + return V8Proxy::EventListenerToV8Object(messagePort->onclose()); +} + +ACCESSOR_SETTER(MessagePortOnclose) +{ + INC_STATS("DOM.MessagePort.onclose._set"); + MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, info.Holder()); + if (value->IsNull()) { + if (messagePort->onclose()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(messagePort->onclose()); + removeHiddenDependency(info.Holder(), listener->getListenerObject(), V8Custom::kXMLHttpRequestCacheIndex); + } + + // Clear the listener. + messagePort->setOnclose(0); + } else { + V8Proxy* proxy = V8Proxy::retrieve(messagePort->scriptExecutionContext()); + if (!proxy) + return; + + RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); + if (listener) { + messagePort->setOnclose(listener); + createHiddenDependency(info.Holder(), value, V8Custom::kMessagePortRequestCacheIndex); + } + } +} + +CALLBACK_FUNC_DECL(MessagePortStartConversation) +{ + INC_STATS("DOM.MessagePort.StartConversation()"); + if (args.Length() < 1) + return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR); + MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, args.Holder()); + + V8Proxy* proxy = V8Proxy::retrieve(messagePort->scriptExecutionContext()); + if (!proxy) + return v8::Undefined(); + + RefPtr<MessagePort> port = messagePort->startConversation(messagePort->scriptExecutionContext(), toWebCoreString(args[0])); + v8::Handle<v8::Value> wrapper = V8Proxy::ToV8Object(V8ClassIndex::MESSAGEPORT, port.get()); + return wrapper; +} + +CALLBACK_FUNC_DECL(MessagePortAddEventListener) +{ + INC_STATS("DOM.MessagePort.AddEventListener()"); + MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, args.Holder()); + + V8Proxy* proxy = V8Proxy::retrieve(messagePort->scriptExecutionContext()); + if (!proxy) + return v8::Undefined(); + + RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(args[1], false); + if (listener) { + String type = toWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + messagePort->addEventListener(type, listener, useCapture); + + createHiddenDependency(args.Holder(), args[1], V8Custom::kMessagePortRequestCacheIndex); + } + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(MessagePortRemoveEventListener) +{ + INC_STATS("DOM.MessagePort.RemoveEventListener()"); + MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, args.Holder()); + + V8Proxy* proxy = V8Proxy::retrieve(messagePort->scriptExecutionContext()); + if (!proxy) + return v8::Undefined(); // probably leaked + + RefPtr<EventListener> listener = proxy->FindObjectEventListener(args[1], false); + + if (listener) { + String type = toWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + messagePort->removeEventListener(type, listener.get(), useCapture); + + removeHiddenDependency(args.Holder(), args[1], V8Custom::kMessagePortRequestCacheIndex); + } + + return v8::Undefined(); +} + +} // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8NodeCustom.cpp b/WebCore/bindings/v8/custom/V8NodeCustom.cpp index bf30414..e81e8b5 100644 --- a/WebCore/bindings/v8/custom/V8NodeCustom.cpp +++ b/WebCore/bindings/v8/custom/V8NodeCustom.cpp @@ -37,6 +37,7 @@ #include "V8Binding.h" #include "V8CustomBinding.h" #include "V8CustomEventListener.h" +#include "V8Node.h" #include "V8Proxy.h" #include <wtf/RefPtr.h> @@ -83,4 +84,77 @@ CALLBACK_FUNC_DECL(NodeRemoveEventListener) return v8::Undefined(); } +// This function is customized to take advantage of the optional 4th argument: shouldLazyAttach +CALLBACK_FUNC_DECL(NodeInsertBefore) +{ + INC_STATS("DOM.Node.insertBefore"); + v8::Handle<v8::Value> holder = args.Holder(); + Node* imp = V8Proxy::DOMWrapperToNode<Node>(holder); + ExceptionCode ec = 0; + Node* newChild = V8Node::HasInstance(args[0]) ? V8Proxy::DOMWrapperToNode<Node>(args[0]) : 0; + Node* refChild = V8Node::HasInstance(args[1]) ? V8Proxy::DOMWrapperToNode<Node>(args[1]) : 0; + bool success = imp->insertBefore(newChild, refChild, ec, true); + if (ec) { + V8Proxy::SetDOMException(ec); + return v8::Handle<v8::Value>(); + } + if (success) + return args[0]; + return v8::Null(); +} + +// This function is customized to take advantage of the optional 4th argument: shouldLazyAttach +CALLBACK_FUNC_DECL(NodeReplaceChild) +{ + INC_STATS("DOM.Node.replaceChild"); + v8::Handle<v8::Value> holder = args.Holder(); + Node* imp = V8Proxy::DOMWrapperToNode<Node>(holder); + ExceptionCode ec = 0; + Node* newChild = V8Node::HasInstance(args[0]) ? V8Proxy::DOMWrapperToNode<Node>(args[0]) : 0; + Node* oldChild = V8Node::HasInstance(args[1]) ? V8Proxy::DOMWrapperToNode<Node>(args[1]) : 0; + bool success = imp->replaceChild(newChild, oldChild, ec, true); + if (ec) { + V8Proxy::SetDOMException(ec); + return v8::Handle<v8::Value>(); + } + if (success) + return args[1]; + return v8::Null(); +} + +CALLBACK_FUNC_DECL(NodeRemoveChild) +{ + INC_STATS("DOM.Node.removeChild"); + v8::Handle<v8::Value> holder = args.Holder(); + Node* imp = V8Proxy::DOMWrapperToNode<Node>(holder); + ExceptionCode ec = 0; + Node* oldChild = V8Node::HasInstance(args[0]) ? V8Proxy::DOMWrapperToNode<Node>(args[0]) : 0; + bool success = imp->removeChild(oldChild, ec); + if (ec) { + V8Proxy::SetDOMException(ec); + return v8::Handle<v8::Value>(); + } + if (success) + return args[0]; + return v8::Null(); +} + +// This function is customized to take advantage of the optional 4th argument: shouldLazyAttach +CALLBACK_FUNC_DECL(NodeAppendChild) +{ + INC_STATS("DOM.Node.appendChild"); + v8::Handle<v8::Value> holder = args.Holder(); + Node* imp = V8Proxy::DOMWrapperToNode<Node>(holder); + ExceptionCode ec = 0; + Node* newChild = V8Node::HasInstance(args[0]) ? V8Proxy::DOMWrapperToNode<Node>(args[0]) : 0; + bool success = imp->appendChild(newChild, ec, true ); + if (ec) { + V8Proxy::SetDOMException(ec); + return v8::Handle<v8::Value>(); + } + if (success) + return args[0]; + return v8::Null(); +} + } // namespace WebCore diff --git a/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp b/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp new file mode 100755 index 0000000..a67cb10 --- /dev/null +++ b/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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(WORKERS) + +#include "WorkerContextExecutionProxy.h" + +#include "ExceptionCode.h" +#include "DOMTimer.h" +#include "NotImplemented.h" +#include "ScheduledAction.h" +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8Proxy.h" +#include "V8Utilities.h" +#include "V8WorkerContextEventListener.h" +#include "WorkerContext.h" + +namespace WebCore { + +ACCESSOR_GETTER(WorkerContextSelf) +{ + INC_STATS(L"DOM.WorkerContext.self._get"); + WorkerContext* workerContext = V8Proxy::ToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, info.Holder()); + return WorkerContextExecutionProxy::WorkerContextToV8Object(workerContext); +} + +ACCESSOR_GETTER(WorkerContextOnmessage) +{ + INC_STATS(L"DOM.WorkerContext.onmessage._get"); + WorkerContext* workerContext = V8Proxy::ToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, info.Holder()); + if (workerContext->onmessage()) { + V8WorkerContextEventListener* listener = static_cast<V8WorkerContextEventListener*>(workerContext->onmessage()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + return v8Listener; + } + return v8::Undefined(); +} + +ACCESSOR_SETTER(WorkerContextOnmessage) +{ + INC_STATS(L"DOM.WorkerContext.onmessage._set"); + WorkerContext* workerContext = V8Proxy::ToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, info.Holder()); + V8WorkerContextEventListener* oldListener = static_cast<V8WorkerContextEventListener*>(workerContext->onmessage()); + if (value->IsNull()) { + if (workerContext->onmessage()) { + v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject(); + removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kWorkerContextRequestCacheIndex); + } + + // Clear the listener. + workerContext->setOnmessage(0); + } else { + RefPtr<V8EventListener> listener = workerContext->script()->proxy()->findOrCreateEventListener(v8::Local<v8::Object>::Cast(value), false, false); + if (listener) { + if (oldListener) { + v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject(); + removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kWorkerContextRequestCacheIndex); + } + + workerContext->setOnmessage(listener); + createHiddenDependency(info.Holder(), value, V8Custom::kWorkerContextRequestCacheIndex); + } + } +} + +v8::Handle<v8::Value> SetTimeoutOrInterval(const v8::Arguments& args, bool singleShot) +{ + WorkerContext* workerContext = V8Proxy::ToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, args.Holder()); + + int argumentCount = args.Length(); + if (argumentCount < 1) + return v8::Undefined(); + + v8::Handle<v8::Value> function = args[0]; + int32_t timeout = argumentCount >= 2 ? args[1]->Int32Value() : 0; + int timerId; + + if (function->IsString()) { + WebCore::String stringFunction = ToWebCoreString(function); + timerId = DOMTimer::install(workerContext, new ScheduledAction(stringFunction, workerContext->url()), timeout, singleShot); + } else if (function->IsFunction()) { + size_t paramCount = argumentCount >= 2 ? argumentCount - 2 : 0; + v8::Local<v8::Value>* params = 0; + if (paramCount > 0) { + params = new v8::Local<v8::Value>[paramCount]; + for (size_t i = 0; i < paramCount; ++i) + params[i] = args[i+2]; + } + // ScheduledAction takes ownership of actual params and releases them in its destructor. + ScheduledAction* action = new ScheduledAction(v8::Handle<v8::Function>::Cast(function), paramCount, params); + delete [] params; + timerId = DOMTimer::install(workerContext, action, timeout, singleShot); + } else + return v8::Undefined(); + + return v8::Integer::New(timerId); +} + +CALLBACK_FUNC_DECL(WorkerContextImportScripts) +{ + INC_STATS(L"DOM.WorkerContext.importScripts()"); + notImplemented(); + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(WorkerContextSetTimeout) +{ + INC_STATS(L"DOM.WorkerContext.setTimeout()"); + return SetTimeoutOrInterval(args, true); +} + +CALLBACK_FUNC_DECL(WorkerContextSetInterval) { + INC_STATS(L"DOM.WorkerContext.setInterval()"); + return SetTimeoutOrInterval(args, false); +} + +CALLBACK_FUNC_DECL(WorkerContextAddEventListener) +{ + INC_STATS(L"DOM.WorkerContext.addEventListener()"); + WorkerContext* workerContext = V8Proxy::ToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, args.Holder()); + + RefPtr<V8EventListener> listener = workerContext->script()->proxy()->findOrCreateEventListener(v8::Local<v8::Object>::Cast(args[1]), false, false); + + if (listener) { + String type = toWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + workerContext->addEventListener(type, listener, useCapture); + + createHiddenDependency(args.Holder(), args[1], V8Custom::kWorkerContextRequestCacheIndex); + } + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(WorkerContextRemoveEventListener) +{ + INC_STATS(L"DOM.WorkerContext.removeEventListener()"); + WorkerContext* workerContext = V8Proxy::ToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, args.Holder()); + WorkerContextExecutionProxy* proxy = workerContext->script()->proxy(); + + RefPtr<V8EventListener> listener = proxy->findOrCreateEventListener(v8::Local<v8::Object>::Cast(args[1]), false, true); + + if (listener) { + String type = toWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + workerContext->removeEventListener(type, listener.get(), useCapture); + + removeHiddenDependency(args.Holder(), args[1], V8Custom::kWorkerContextRequestCacheIndex); + } + + return v8::Undefined(); +} + +} // namespace WebCore + +#endif // ENABLE(WORKERS) diff --git a/WebCore/bindings/v8/custom/V8WorkerCustom.cpp b/WebCore/bindings/v8/custom/V8WorkerCustom.cpp new file mode 100755 index 0000000..3edaa8e --- /dev/null +++ b/WebCore/bindings/v8/custom/V8WorkerCustom.cpp @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2009 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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(WORKERS) + +#include "Worker.h" + +#include "ExceptionCode.h" +#include "Frame.h" +#include "V8Binding.h" +#include "V8CustomBinding.h" +#include "V8ObjectEventListener.h" +#include "V8Proxy.h" +#include "V8Utilities.h" +#include "WorkerContext.h" +#include "WorkerContextExecutionProxy.h" + +namespace WebCore { + +CALLBACK_FUNC_DECL(WorkerConstructor) +{ + INC_STATS(L"DOM.Worker.Constructor"); + + if (!WorkerContextExecutionProxy::isWebWorkersEnabled()) { + return throwError("Worker is not enabled.", V8Proxy::SYNTAX_ERROR); + } + + if (!args.IsConstructCall()) { + return throwError("DOM object constructor cannot be called as a function."); + } + + if (args.Length() == 0) { + return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR); + } + + v8::TryCatch tryCatch; + v8::Handle<v8::String> scriptUrl = args[0]->ToString(); + if (tryCatch.HasCaught()) { + return throwError(tryCatch.Exception()); + } + if (scriptUrl.IsEmpty()) + return v8::Undefined(); + + // Get the script execution context. + ScriptExecutionContext* context = 0; + WorkerContextExecutionProxy* proxy = WorkerContextExecutionProxy::retrieve(); + if (proxy) + context = proxy->workerContext(); + else { + Frame* frame = V8Proxy::retrieveFrame(); + if (!frame) + return v8::Undefined(); + context = frame->document(); + } + + // Create the worker object. + // Note: it's OK to let this RefPtr go out of scope because we also call SetDOMWrapper(), which effectively holds a reference to obj. + ExceptionCode ec = 0; + RefPtr<Worker> obj = Worker::create(toWebCoreString(scriptUrl), context, ec); + + // Setup the standard wrapper object internal fields. + v8::Handle<v8::Object> wrapperObject = args.Holder(); + V8Proxy::SetDOMWrapper(wrapperObject, V8ClassIndex::WORKER, obj.get()); + + obj->ref(); + V8Proxy::SetJSWrapperForActiveDOMObject(obj.get(), v8::Persistent<v8::Object>::New(wrapperObject)); + + return wrapperObject; +} + +PassRefPtr<EventListener> getEventListener(Worker* worker, v8::Local<v8::Value> value, bool findOnly) +{ + if (worker->scriptExecutionContext()->isWorkerContext()) { + WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve(); + ASSERT(workerContextProxy); + return workerContextProxy->findOrCreateObjectEventListener(value, false, findOnly); + } + + V8Proxy* proxy = V8Proxy::retrieve(worker->scriptExecutionContext()); + if (proxy) + return findOnly ? proxy->FindObjectEventListener(value, false) : proxy->FindOrCreateObjectEventListener(value, false); + + return 0; +} + +ACCESSOR_GETTER(WorkerOnmessage) +{ + INC_STATS(L"DOM.Worker.onmessage._get"); + Worker* worker = V8Proxy::ToNativeObject<Worker>(V8ClassIndex::WORKER, info.Holder()); + if (worker->onmessage()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(worker->onmessage()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + return v8Listener; + } + return v8::Undefined(); +} + +ACCESSOR_SETTER(WorkerOnmessage) +{ + INC_STATS(L"DOM.Worker.onmessage._set"); + Worker* worker = V8Proxy::ToNativeObject<Worker>(V8ClassIndex::WORKER, info.Holder()); + V8ObjectEventListener* oldListener = static_cast<V8ObjectEventListener*>(worker->onmessage()); + if (value->IsNull()) { + if (oldListener) { + v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject(); + removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kWorkerRequestCacheIndex); + } + + // Clear the listener. + worker->setOnmessage(0); + } else { + RefPtr<EventListener> listener = getEventListener(worker, value, false); + if (listener) { + if (oldListener) { + v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject(); + removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kWorkerRequestCacheIndex); + } + + worker->setOnmessage(listener); + createHiddenDependency(info.Holder(), value, V8Custom::kWorkerRequestCacheIndex); + } + } +} + +ACCESSOR_GETTER(WorkerOnerror) +{ + INC_STATS(L"DOM.Worker.onerror._get"); + Worker* worker = V8Proxy::ToNativeObject<Worker>(V8ClassIndex::WORKER, info.Holder()); + if (worker->onerror()) { + V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(worker->onerror()); + v8::Local<v8::Object> v8Listener = listener->getListenerObject(); + return v8Listener; + } + return v8::Undefined(); +} + +ACCESSOR_SETTER(WorkerOnerror) +{ + INC_STATS(L"DOM.Worker.onerror._set"); + Worker* worker = V8Proxy::ToNativeObject<Worker>(V8ClassIndex::WORKER, info.Holder()); + V8ObjectEventListener* oldListener = static_cast<V8ObjectEventListener*>(worker->onerror()); + if (value->IsNull()) { + if (oldListener) { + v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject(); + removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kWorkerRequestCacheIndex); + } + + // Clear the listener. + worker->setOnerror(0); + } else { + RefPtr<EventListener> listener = getEventListener(worker, value, false); + if (listener) { + if (oldListener) { + v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject(); + removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kWorkerRequestCacheIndex); + } + + worker->setOnerror(listener); + createHiddenDependency(info.Holder(), value, V8Custom::kWorkerRequestCacheIndex); + } + } +} + +CALLBACK_FUNC_DECL(WorkerAddEventListener) +{ + INC_STATS(L"DOM.Worker.addEventListener()"); + Worker* worker = V8Proxy::ToNativeObject<Worker>(V8ClassIndex::WORKER, args.Holder()); + + RefPtr<EventListener> listener = getEventListener(worker, args[1], false); + if (listener) { + String type = toWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + worker->addEventListener(type, listener, useCapture); + + createHiddenDependency(args.Holder(), args[1], V8Custom::kWorkerRequestCacheIndex); + } + return v8::Undefined(); +} + +CALLBACK_FUNC_DECL(WorkerRemoveEventListener) +{ + INC_STATS(L"DOM.Worker.removeEventListener()"); + Worker* worker = V8Proxy::ToNativeObject<Worker>(V8ClassIndex::WORKER, args.Holder()); + + RefPtr<EventListener> listener = getEventListener(worker, args[1], true); + if (listener) { + String type = toWebCoreString(args[0]); + bool useCapture = args[2]->BooleanValue(); + worker->removeEventListener(type, listener.get(), useCapture); + + removeHiddenDependency(args.Holder(), args[1], V8Custom::kWorkerRequestCacheIndex); + } + + return v8::Undefined(); +} + +} // namespace WebCore + +#endif // ENABLE(WORKERS) diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp index 6b55238..c913c08 100644 --- a/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp +++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp @@ -36,6 +36,8 @@ #include "V8ObjectEventListener.h" #include "V8Proxy.h" #include "XMLHttpRequest.h" +#include "WorkerContext.h" +#include "WorkerContextExecutionProxy.h" namespace WebCore { @@ -48,8 +50,15 @@ CALLBACK_FUNC_DECL(XMLHttpRequestConstructor) // Expect no parameters. // Allocate a XMLHttpRequest object as its internal field. - Document* doc = V8Proxy::retrieveFrame()->document(); - RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(doc); + ScriptExecutionContext* context = 0; +#if ENABLE(WORKERS) + WorkerContextExecutionProxy* proxy = WorkerContextExecutionProxy::retrieve(); + if (proxy) + context = proxy->workerContext(); + else +#endif + context = V8Proxy::retrieveFrame()->document(); + RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(context); V8Proxy::SetDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::XMLHTTPREQUEST), xmlHttpRequest.get()); // Add object to the wrapper map. diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp index ea69f0b..cb80a4f 100644 --- a/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp +++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp @@ -38,10 +38,27 @@ #include "V8HTMLDocument.h" #include "V8ObjectEventListener.h" #include "V8Proxy.h" -#include "V8XMLHttpRequestUtilities.h" +#include "V8Utilities.h" +#include "WorkerContext.h" +#include "WorkerContextExecutionProxy.h" namespace WebCore { +PassRefPtr<EventListener> getEventListener(XMLHttpRequest* xmlHttpRequest, v8::Local<v8::Value> value, bool findOnly) +{ +#if ENABLE(WORKERS) + WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve(); + if (workerContextProxy) + return workerContextProxy->findOrCreateObjectEventListener(value, false, findOnly); +#endif + + V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); + if (proxy) + return findOnly ? proxy->FindObjectEventListener(value, false) : proxy->FindOrCreateObjectEventListener(value, false); + + return PassRefPtr<EventListener>(); +} + ACCESSOR_GETTER(XMLHttpRequestOnabort) { INC_STATS("DOM.XMLHttpRequest.onabort._get"); @@ -51,7 +68,7 @@ ACCESSOR_GETTER(XMLHttpRequestOnabort) v8::Local<v8::Object> v8Listener = listener->getListenerObject(); return v8Listener; } - return v8::Undefined(); + return v8::Null(); } ACCESSOR_SETTER(XMLHttpRequestOnabort) @@ -62,20 +79,16 @@ ACCESSOR_SETTER(XMLHttpRequestOnabort) if (xmlHttpRequest->onabort()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onabort()); v8::Local<v8::Object> v8Listener = listener->getListenerObject(); - removeHiddenXHRDependency(info.Holder(), v8Listener); + removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex); } // Clear the listener. xmlHttpRequest->setOnabort(0); } else { - V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); - if (!proxy) - return; - - RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); + RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, value, false); if (listener) { xmlHttpRequest->setOnabort(listener); - createHiddenXHRDependency(info.Holder(), value); + createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex); } } } @@ -89,7 +102,7 @@ ACCESSOR_GETTER(XMLHttpRequestOnerror) v8::Local<v8::Object> v8Listener = listener->getListenerObject(); return v8Listener; } - return v8::Undefined(); + return v8::Null(); } ACCESSOR_SETTER(XMLHttpRequestOnerror) @@ -100,20 +113,16 @@ ACCESSOR_SETTER(XMLHttpRequestOnerror) if (xmlHttpRequest->onerror()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onerror()); v8::Local<v8::Object> v8Listener = listener->getListenerObject(); - removeHiddenXHRDependency(info.Holder(), v8Listener); + removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex); } // Clear the listener. xmlHttpRequest->setOnerror(0); } else { - V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); - if (!proxy) - return; - - RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); + RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, value, false); if (listener) { xmlHttpRequest->setOnerror(listener); - createHiddenXHRDependency(info.Holder(), value); + createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex); } } } @@ -127,7 +136,7 @@ ACCESSOR_GETTER(XMLHttpRequestOnload) v8::Local<v8::Object> v8Listener = listener->getListenerObject(); return v8Listener; } - return v8::Undefined(); + return v8::Null(); } ACCESSOR_SETTER(XMLHttpRequestOnload) @@ -138,20 +147,16 @@ ACCESSOR_SETTER(XMLHttpRequestOnload) if (xmlHttpRequest->onload()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onload()); v8::Local<v8::Object> v8Listener = listener->getListenerObject(); - removeHiddenXHRDependency(info.Holder(), v8Listener); + removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex); } xmlHttpRequest->setOnload(0); } else { - V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); - if (!proxy) - return; - - RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); + RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, value, false); if (listener) { xmlHttpRequest->setOnload(listener.get()); - createHiddenXHRDependency(info.Holder(), value); + createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex); } } } @@ -165,7 +170,7 @@ ACCESSOR_GETTER(XMLHttpRequestOnloadstart) v8::Local<v8::Object> v8Listener = listener->getListenerObject(); return v8Listener; } - return v8::Undefined(); + return v8::Null(); } ACCESSOR_SETTER(XMLHttpRequestOnloadstart) @@ -176,20 +181,16 @@ ACCESSOR_SETTER(XMLHttpRequestOnloadstart) if (xmlHttpRequest->onloadstart()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onloadstart()); v8::Local<v8::Object> v8Listener = listener->getListenerObject(); - removeHiddenXHRDependency(info.Holder(), v8Listener); + removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex); } // Clear the listener. xmlHttpRequest->setOnloadstart(0); } else { - V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); - if (!proxy) - return; - - RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); + RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, value, false); if (listener) { xmlHttpRequest->setOnloadstart(listener); - createHiddenXHRDependency(info.Holder(), value); + createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex); } } } @@ -203,7 +204,7 @@ ACCESSOR_GETTER(XMLHttpRequestOnprogress) v8::Local<v8::Object> v8Listener = listener->getListenerObject(); return v8Listener; } - return v8::Undefined(); + return v8::Null(); } ACCESSOR_SETTER(XMLHttpRequestOnprogress) @@ -214,20 +215,16 @@ ACCESSOR_SETTER(XMLHttpRequestOnprogress) if (xmlHttpRequest->onprogress()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onprogress()); v8::Local<v8::Object> v8Listener = listener->getListenerObject(); - removeHiddenXHRDependency(info.Holder(), v8Listener); + removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex); } // Clear the listener. xmlHttpRequest->setOnprogress(0); } else { - V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); - if (!proxy) - return; - - RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); + RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, value, false); if (listener) { xmlHttpRequest->setOnprogress(listener); - createHiddenXHRDependency(info.Holder(), value); + createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex); } } } @@ -241,7 +238,7 @@ ACCESSOR_GETTER(XMLHttpRequestOnreadystatechange) v8::Local<v8::Object> v8Listener = listener->getListenerObject(); return v8Listener; } - return v8::Undefined(); + return v8::Null(); } ACCESSOR_SETTER(XMLHttpRequestOnreadystatechange) @@ -252,20 +249,16 @@ ACCESSOR_SETTER(XMLHttpRequestOnreadystatechange) if (xmlHttpRequest->onreadystatechange()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onreadystatechange()); v8::Local<v8::Object> v8Listener = listener->getListenerObject(); - removeHiddenXHRDependency(info.Holder(), v8Listener); + removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex); } // Clear the listener. xmlHttpRequest->setOnreadystatechange(0); } else { - V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); - if (!proxy) - return; - - RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); + RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, value, false); if (listener) { xmlHttpRequest->setOnreadystatechange(listener.get()); - createHiddenXHRDependency(info.Holder(), value); + createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex); } } } @@ -284,17 +277,13 @@ CALLBACK_FUNC_DECL(XMLHttpRequestAddEventListener) INC_STATS("DOM.XMLHttpRequest.addEventListener()"); XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder()); - V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); - if (!proxy) - return v8::Undefined(); - - RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(args[1], false); + RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, args[1], false); if (listener) { String type = toWebCoreString(args[0]); bool useCapture = args[2]->BooleanValue(); xmlHttpRequest->addEventListener(type, listener, useCapture); - createHiddenXHRDependency(args.Holder(), args[1]); + createHiddenDependency(args.Holder(), args[1], V8Custom::kXMLHttpRequestCacheIndex); } return v8::Undefined(); } @@ -304,18 +293,13 @@ CALLBACK_FUNC_DECL(XMLHttpRequestRemoveEventListener) INC_STATS("DOM.XMLHttpRequest.removeEventListener()"); XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder()); - V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext()); - if (!proxy) - return v8::Undefined(); // Probably leaked. - - RefPtr<EventListener> listener = proxy->FindObjectEventListener(args[1], false); - + RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, args[1], true); if (listener) { String type = toWebCoreString(args[0]); bool useCapture = args[2]->BooleanValue(); xmlHttpRequest->removeEventListener(type, listener.get(), useCapture); - removeHiddenXHRDependency(args.Holder(), args[1]); + removeHiddenDependency(args.Holder(), args[1], V8Custom::kXMLHttpRequestCacheIndex); } return v8::Undefined(); @@ -337,8 +321,24 @@ CALLBACK_FUNC_DECL(XMLHttpRequestOpen) String method = toWebCoreString(args[0]); String urlstring = toWebCoreString(args[1]); - V8Proxy* proxy = V8Proxy::retrieve(); - KURL url = proxy->frame()->document()->completeURL(urlstring); + ScriptExecutionContext* context = 0; +#if ENABLE(WORKERS) + WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve(); + if (workerContextProxy) { + context = workerContextProxy->workerContext(); + ASSERT(context); + } +#endif + + if (!context) { + V8Proxy* proxy = V8Proxy::retrieve(); + if (!proxy) + return v8::Undefined(); + context = proxy->frame()->document(); + ASSERT(context); + } + + KURL url = context->completeURL(urlstring); bool async = (args.Length() < 3) ? true : args[2]->BooleanValue(); diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp index 7ffad82..7afa82c 100644 --- a/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp +++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp @@ -36,7 +36,7 @@ #include "V8CustomBinding.h" #include "V8ObjectEventListener.h" #include "V8Proxy.h" -#include "V8XMLHttpRequestUtilities.h" +#include "V8Utilities.h" #include "XMLHttpRequest.h" #include <wtf/Assertions.h> @@ -52,7 +52,7 @@ ACCESSOR_GETTER(XMLHttpRequestUploadOnabort) v8::Local<v8::Object> v8Listener = listener->getListenerObject(); return v8Listener; } - return v8::Undefined(); + return v8::Null(); } ACCESSOR_SETTER(XMLHttpRequestUploadOnabort) @@ -63,7 +63,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnabort) if (xmlHttpRequestUpload->onabort()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onabort()); v8::Local<v8::Object> v8Listener = listener->getListenerObject(); - removeHiddenXHRDependency(info.Holder(), v8Listener); + removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex); } // Clear the listener. @@ -77,7 +77,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnabort) RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); if (listener) { xmlHttpRequestUpload->setOnabort(listener); - createHiddenXHRDependency(info.Holder(), value); + createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex); } } } @@ -91,7 +91,7 @@ ACCESSOR_GETTER(XMLHttpRequestUploadOnerror) v8::Local<v8::Object> v8Listener = listener->getListenerObject(); return v8Listener; } - return v8::Undefined(); + return v8::Null(); } ACCESSOR_SETTER(XMLHttpRequestUploadOnerror) @@ -102,7 +102,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnerror) if (xmlHttpRequestUpload->onerror()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onerror()); v8::Local<v8::Object> v8Listener = listener->getListenerObject(); - removeHiddenXHRDependency(info.Holder(), v8Listener); + removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex); } // Clear the listener. @@ -116,7 +116,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnerror) RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); if (listener) { xmlHttpRequestUpload->setOnerror(listener); - createHiddenXHRDependency(info.Holder(), value); + createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex); } } } @@ -130,7 +130,7 @@ ACCESSOR_GETTER(XMLHttpRequestUploadOnload) v8::Local<v8::Object> v8Listener = listener->getListenerObject(); return v8Listener; } - return v8::Undefined(); + return v8::Null(); } ACCESSOR_SETTER(XMLHttpRequestUploadOnload) @@ -141,7 +141,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnload) if (xmlHttpRequestUpload->onload()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onload()); v8::Local<v8::Object> v8Listener = listener->getListenerObject(); - removeHiddenXHRDependency(info.Holder(), v8Listener); + removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex); } // Clear the listener. @@ -155,7 +155,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnload) RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); if (listener) { xmlHttpRequestUpload->setOnload(listener); - createHiddenXHRDependency(info.Holder(), value); + createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex); } } } @@ -169,7 +169,7 @@ ACCESSOR_GETTER(XMLHttpRequestUploadOnloadstart) v8::Local<v8::Object> v8Listener = listener->getListenerObject(); return v8Listener; } - return v8::Undefined(); + return v8::Null(); } ACCESSOR_SETTER(XMLHttpRequestUploadOnloadstart) @@ -180,7 +180,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnloadstart) if (xmlHttpRequestUpload->onloadstart()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onloadstart()); v8::Local<v8::Object> v8Listener = listener->getListenerObject(); - removeHiddenXHRDependency(info.Holder(), v8Listener); + removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex); } // Clear the listener. @@ -194,7 +194,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnloadstart) RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); if (listener) { xmlHttpRequestUpload->setOnloadstart(listener); - createHiddenXHRDependency(info.Holder(), value); + createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex); } } } @@ -208,7 +208,7 @@ ACCESSOR_GETTER(XMLHttpRequestUploadOnprogress) v8::Local<v8::Object> v8Listener = listener->getListenerObject(); return v8Listener; } - return v8::Undefined(); + return v8::Null(); } ACCESSOR_SETTER(XMLHttpRequestUploadOnprogress) @@ -219,7 +219,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnprogress) if (xmlHttpRequestUpload->onprogress()) { V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onprogress()); v8::Local<v8::Object> v8Listener = listener->getListenerObject(); - removeHiddenXHRDependency(info.Holder(), v8Listener); + removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex); } // Clear the listener. @@ -233,7 +233,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnprogress) RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false); if (listener) { xmlHttpRequestUpload->setOnprogress(listener); - createHiddenXHRDependency(info.Holder(), value); + createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex); } } } @@ -254,7 +254,7 @@ CALLBACK_FUNC_DECL(XMLHttpRequestUploadAddEventListener) bool useCapture = args[2]->BooleanValue(); xmlHttpRequestUpload->addEventListener(type, listener, useCapture); - createHiddenXHRDependency(args.Holder(), args[1]); + createHiddenDependency(args.Holder(), args[1], V8Custom::kXMLHttpRequestCacheIndex); } return v8::Undefined(); } @@ -276,7 +276,7 @@ CALLBACK_FUNC_DECL(XMLHttpRequestUploadRemoveEventListener) bool useCapture = args[2]->BooleanValue(); xmlHttpRequestUpload->removeEventListener(type, listener.get(), useCapture); - removeHiddenXHRDependency(args.Holder(), args[1]); + removeHiddenDependency(args.Holder(), args[1], V8Custom::kXMLHttpRequestCacheIndex); } return v8::Undefined(); |