+2006-04-27 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Maciej
+
+ - Minor fixups I discovered while working on the autogenerator.
+
+ * kjs/lookup.cpp:
+ (findEntry): ASSERT that size is not 0, because otherwise we'll % by 0,
+ compute a garbage address, and possibly crash.
+ * kjs/lookup.h:
+ (cacheGlobalObject): Don't enumerate cached objects -- ideally, they
+ would be hidden entirely.
+
2006-04-21 Kevin M. Ollivier <kevino@theolliviers.com>
Reviewed by Darin.
#include <string.h>
#include "lookup.h"
+#include <kxmlcore/Assertions.h>
using namespace KJS;
return 0;
}
#endif
+ ASSERT(table->hashSize != 0);
+
hash %= table->hashSize;
const HashEntry *e = &table->entries[hash];
return static_cast<KJS::JSObject *>(obj);
}
KJS::JSObject *newObject = new ClassCtor(exec);
- globalObject->put(exec, propertyName, newObject, KJS::Internal);
+ globalObject->put(exec, propertyName, newObject, KJS::Internal | KJS::DontEnum);
return newObject;
}
+2006-04-27 Geoffrey Garen <ggaren@apple.com>
+
+ - Updated to remove diff shmutz:
+
+ * fast/dom/Window/window-special-properties-expected.txt:
+ * fast/dom/Window/window-special-properties.html:
+
+ - Test for global window properties like window.HTMLDocument:
+
+ * fast/dom/global-constructors-expected.txt: Added.
+ * fast/dom/global-constructors.html: Added.
+
2006-04-27 Mitz Pettel <opendarwin.org@mitzpettel.com>
Reviewed by darin
Conflicting image: single OTHER
Conflicting image (custom property): single OTHER
Conflicting iframe: single WINDOW
-\ No newline at end of file
+
</script>
</body>
-\ No newline at end of file
--- /dev/null
+This page tests global constructor objects like window.HTMLDocument. If it passes, you'll see a series of 'PASS' messages below.
+
+PASS: window.Document.prototype.isPrototypeOf(document) should be true and is.
+PASS: window.Node.prototype.isPrototypeOf(element) should be true and is.
+PASS: window.Element.prototype.isPrototypeOf(element) should be true and is.
+PASS: window.Range.prototype.isPrototypeOf(range) should be true and is.
+PASS: window.CSSRule.prototype.isPrototypeOf(cssRule) should be true and is.
+PASS: window.CSSValue.prototype.isPrototypeOf(cssPrimitiveValue) should be true and is.
+PASS: window.CSSPrimitiveValue.prototype.isPrototypeOf(cssPrimitiveValue) should be true and is.
+PASS: window.CSSStyleDeclaration.prototype.isPrototypeOf(cssStyleDeclaration) should be true and is.
+PASS: window.Event.prototype.isPrototypeOf(event) should be true and is.
+PASS: window.MutationEvent.prototype.isPrototypeOf(event) should be true and is.
+PASS: window.NodeFilter.prototype.isPrototypeOf(nodeFilter) should be true and is.
+[Deleted window.Node.prototype]
+PASS: window.Node.prototype should be undefined and is.
+[Set window.Node = 1]
+PASS: window.Node should be 1 and is.
+[Deleted window.Node]
+PASS: window.Node should be [object NodeConstructor] and is.
+[Added an iframe named 'Node']
+PASS: window.Node should be [object NodeConstructor] and is.
+
--- /dev/null
+<html>
+<head>
+<style>
+ * {
+ color: black;
+ }
+</style>
+<script>
+function print(message, color)
+{
+ var paragraph = document.createElement("div");
+ paragraph.appendChild(document.createTextNode(message));
+ paragraph.style.fontFamily = "monospace";
+ if (color)
+ paragraph.style.color = color;
+ document.getElementById("console").appendChild(paragraph);
+}
+
+var element, range, nodeFilter, cssRule, cssPrimitiveValue, cssStyleDeclaration, event;
+var originalNodeConstructor;
+
+function shouldBe(a, b)
+{
+ var evalA;
+ try {
+ evalA = eval(a);
+ } catch(e) {
+ evalA = e;
+ }
+ if (evalA == b)
+ print("PASS: " + a + " should be " + b + " and is.", "green");
+ else
+ print("FAIL: " + a + " should be " + b + " but instead is " + evalA, "red");
+}
+
+function test()
+{
+ if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+ shouldBe("window.Document.prototype.isPrototypeOf(document)", true);
+
+ element = document.body;
+ shouldBe("window.Node.prototype.isPrototypeOf(element)", true);
+ shouldBe("window.Element.prototype.isPrototypeOf(element)", true);
+
+ range = document.createRange();
+ shouldBe("window.Range.prototype.isPrototypeOf(range)", true);
+
+ cssRule = document.styleSheets[0].cssRules[0];
+ shouldBe("window.CSSRule.prototype.isPrototypeOf(cssRule)", true);
+
+ cssPrimitiveValue = cssRule.style.getPropertyCSSValue("color");
+ shouldBe("window.CSSValue.prototype.isPrototypeOf(cssPrimitiveValue)", true);
+ shouldBe("window.CSSPrimitiveValue.prototype.isPrototypeOf(cssPrimitiveValue)", true);
+
+ cssStyleDeclaration = cssRule.style;
+ shouldBe("window.CSSStyleDeclaration.prototype.isPrototypeOf(cssStyleDeclaration)", true);
+
+ event = document.createEvent("MutationEvents");
+ shouldBe("window.Event.prototype.isPrototypeOf(event)", true);
+ shouldBe("window.MutationEvent.prototype.isPrototypeOf(event)", true);
+
+ try {
+ nodeFilter = document.createNodeIterator(document, NodeFilter.SHOW_ELEMENT, function () {}, false).filter;
+ } catch(e) {}
+ shouldBe("window.NodeFilter.prototype.isPrototypeOf(nodeFilter)", true);
+
+ delete window.Node.prototype;
+ print("[Deleted window.Node.prototype]");
+ shouldBe("window.Node.prototype", undefined);
+
+ originalNodeConstructor = window.Node;
+
+ // Shadow window.Node
+ window.Node = 1;
+ print("[Set window.Node = 1]");
+ shouldBe("window.Node", 1);
+
+ // Unshadow window.Node
+ delete window.Node;
+ print("[Deleted window.Node]");
+ shouldBe("window.Node", originalNodeConstructor);
+
+ // Attempt to shadow window.Node with a frame named 'Node'
+ var iframe = document.createElement('iframe');
+ iframe.setAttribute('name', "Node");
+ document.body.appendChild(iframe);
+ print("[Added an iframe named 'Node']");
+ shouldBe("window.Node", originalNodeConstructor);
+
+}
+</script>
+</head>
+
+<body onload="test();">
+<p>This page tests global constructor objects like window.HTMLDocument. If it passes, you'll
+ see a series of 'PASS' messages below.
+</p>
+<hr>
+<div id='console'></div>
+
+</body>
+</html>
+2006-04-27 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Maciej.
+
+ - Added global constructor autogeneration for the following,
+ many of which are required by *.live.com: Node, Element, Range,
+ CSSRule, CSSValue, CSSPrimitiveValue, CSSStyleDeclaration, Event,
+ MutationEvent, NodeFilter
+
+ It works like so:
+
+ - The autogenerator knows about the "Constructor" data type, which
+ gets special treatment because it exists purely in the
+ bindings. It also knows about the "GenerateConstructor" interface
+ attribute, which does just that.
+
+ - The window interface has many Constructor attributes
+
+ - The hash table generator swizzles empty tables to tables with one
+ empty bucket, to prevent crashes in Lookup::findEntry. (The old
+ generator used to work this way, too.)
+
+ - Window object property lookup gets special treatment to allow
+ shadowing of its built-in global constructor properties. We'll
+ need to expand this mechanism in the future and make it more
+ flexible, but it works for now.
+
+ * DerivedSources.make:
+ * WebCore.vcproj/WebCore/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * bindings/js/kjs_css.cpp:
+ (KJS::toJS):
+ * bindings/js/kjs_css.h:
+ * bindings/js/kjs_window.cpp: Removed 'namedFrameGetter' and its use
+ because they were bogus; added FIXME describing what they were
+ attempting to do.
+ (KJS::Window::getValueProperty):
+ (KJS::Window::getOverridePropertySlot):
+ (KJS::Window::getOwnPropertySlot):
+ * bindings/js/kjs_window.h:
+ (KJS::Window::):
+ * bindings/scripts/CodeGeneratorJS.pm:
+ * css/CSSPrimitiveValue.idl:
+ * css/CSSRule.idl:
+ * css/CSSStyleDeclaration.idl: Added.
+ * css/CSSValue.idl:
+ * dom/Document.idl:
+ * dom/Element.idl:
+ * dom/Event.idl:
+ * dom/MutationEvent.idl:
+ * dom/Node.idl:
+ * dom/NodeFilter.idl:
+ * dom/Range.idl:
+ * page/DOMWindow.idl:
+
2006-04-27 Mitz Pettel <opendarwin.org@mitzpettel.com>
Reviewed by darin
JSCanvasRenderingContext2DBaseTable.cpp \
JSCharacterData.h \
JSCounter.h \
+ JSCSSStyleDeclaration.h \
JSDOMImplementation.h \
JSDOMParser.lut.h \
JSDOMWindow.h \
RelativePath="..\..\DerivedSources\WebCore\JSCSSRule.cpp"\r
>\r
</File>\r
+\r
+ RelativePath="..\..\DerivedSources\WebCore\JSCSSStyleDeclaration.cpp"\r
+ >\r
+ </File>\r
<File\r
RelativePath="..\..\DerivedSources\WebCore\JSCSSValue.cpp"\r
>\r
14115B5209F84B7100CA4FC1 /* Node.h in Headers */ = {isa = PBXBuildFile; fileRef = 14115B5109F84B7100CA4FC1 /* Node.h */; };
14115B7209F84CD600CA4FC1 /* JSNodeFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14115B7009F84CD600CA4FC1 /* JSNodeFilter.cpp */; };
14115B7309F84CD600CA4FC1 /* JSNodeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 14115B7109F84CD600CA4FC1 /* JSNodeFilter.h */; };
+ 142011AF0A003117008303F9 /* CSSStyleDeclaration.idl in Resources */ = {isa = PBXBuildFile; fileRef = 142011AE0A003117008303F9 /* CSSStyleDeclaration.idl */; };
+ 142011B60A003133008303F9 /* JSCSSStyleDeclaration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 142011B40A003133008303F9 /* JSCSSStyleDeclaration.cpp */; };
+ 142011B70A003133008303F9 /* JSCSSStyleDeclaration.h in Headers */ = {isa = PBXBuildFile; fileRef = 142011B50A003133008303F9 /* JSCSSStyleDeclaration.h */; };
14CF787209F587CA00EB3665 /* CSSValue.idl in Resources */ = {isa = PBXBuildFile; fileRef = 14CF787109F587CA00EB3665 /* CSSValue.idl */; };
14CF78A409F58CBF00EB3665 /* JSCSSValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14CF78A309F58CBF00EB3665 /* JSCSSValue.cpp */; };
14CF78A609F58CD800EB3665 /* JSCSSValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 14CF78A509F58CD800EB3665 /* JSCSSValue.h */; };
14115B7109F84CD600CA4FC1 /* JSNodeFilter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSNodeFilter.h; sourceTree = "<group>"; };
141B94E509EC4223000E9413 /* MouseEvent.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = MouseEvent.idl; sourceTree = "<group>"; };
141B94EE09EC425A000E9413 /* UIEvent.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = UIEvent.idl; sourceTree = "<group>"; };
+ 142011AE0A003117008303F9 /* CSSStyleDeclaration.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = CSSStyleDeclaration.idl; sourceTree = "<group>"; };
+ 142011B40A003133008303F9 /* JSCSSStyleDeclaration.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSCSSStyleDeclaration.cpp; sourceTree = "<group>"; };
+ 142011B50A003133008303F9 /* JSCSSStyleDeclaration.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSCSSStyleDeclaration.h; sourceTree = "<group>"; };
14813BF309EDF88E00F757E1 /* IDLParser.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; name = IDLParser.pm; path = scripts/IDLParser.pm; sourceTree = "<group>"; };
14CF787109F587CA00EB3665 /* CSSValue.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = CSSValue.idl; sourceTree = "<group>"; };
14CF78A309F58CBF00EB3665 /* JSCSSValue.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSCSSValue.cpp; sourceTree = "<group>"; };
656580EC09D12B20000E61D7 /* Derived Sources */ = {
isa = PBXGroup;
children = (
- 14DC0D3509FED073007B0235 /* JSNode.cpp */,
- 14DC0D3609FED073007B0235 /* JSNode.h */,
656581AC09D14EE6000E61D7 /* CharsetData.cpp */,
656581AD09D14EE6000E61D7 /* ColorData.c */,
6565814409D13043000E61D7 /* CSSGrammar.cpp */,
930705EA09E0C9F600B17FE4 /* JSCSSPrimitiveValue.h */,
14CF7B3109F6ECD700EB3665 /* JSCSSRule.cpp */,
14CF7B3209F6ECD700EB3665 /* JSCSSRule.h */,
+ 142011B40A003133008303F9 /* JSCSSStyleDeclaration.cpp */,
14CF78A309F58CBF00EB3665 /* JSCSSValue.cpp */,
14CF78A509F58CD800EB3665 /* JSCSSValue.h */,
659DDC8009E198BA001BF3C6 /* JSDocument.cpp */,
A86629CB09DA2B47009633A5 /* JSMouseEvent.h */,
65DF31E709D1CC60000BE325 /* JSMutationEvent.cpp */,
65DF31E809D1CC60000BE325 /* JSMutationEvent.h */,
+ 14DC0D3509FED073007B0235 /* JSNode.cpp */,
+ 14DC0D3609FED073007B0235 /* JSNode.h */,
14115B7009F84CD600CA4FC1 /* JSNodeFilter.cpp */,
14115B7109F84CD600CA4FC1 /* JSNodeFilter.h */,
65DF31E909D1CC60000BE325 /* JSNotation.cpp */,
656581AF09D14EE6000E61D7 /* UserAgentStyleSheetsData.cpp */,
656581EA09D1508D000E61D7 /* XLinkNames.cpp */,
656581EB09D1508D000E61D7 /* XLinkNames.h */,
+ 142011B50A003133008303F9 /* JSCSSStyleDeclaration.h */,
);
name = "Derived Sources";
path = DerivedSources/WebCore;
F523D18402DE42E8018635CA /* css */ = {
isa = PBXGroup;
children = (
- 14CF7A7009F5CF9A00EB3665 /* CSSRule.idl */,
- 14CF787109F587CA00EB3665 /* CSSValue.idl */,
+ 142011AE0A003117008303F9 /* CSSStyleDeclaration.idl */,
930705C709E0C95F00B17FE4 /* Counter.idl */,
BCEA477A097CAAC80094C9E4 /* css_base.cpp */,
BCEA477B097CAAC80094C9E4 /* css_base.h */,
BCEA4788097CAAC80094C9E4 /* cssparser.h */,
9307059009E0C75800B17FE4 /* CSSPrimitiveValue.idl */,
BCEA4789097CAAC80094C9E4 /* CSSPropertyNames.in */,
+ 14CF7A7009F5CF9A00EB3665 /* CSSRule.idl */,
BCEA478A097CAAC80094C9E4 /* cssstyleselector.cpp */,
BCEA478B097CAAC80094C9E4 /* cssstyleselector.h */,
+ 14CF787109F587CA00EB3665 /* CSSValue.idl */,
BCEA478C097CAAC80094C9E4 /* CSSValueKeywords.in */,
93CA4C9909DF93FA00DF8677 /* html4.css */,
93CA4C9A09DF93FA00DF8677 /* make-css-file-arrays.pl */,
65901A4409FC6039005BD752 /* WebCoreStringTruncator.h in Headers */,
14DC0D3809FED073007B0235 /* JSNode.h in Headers */,
14D0C82509FF0EF5006B36D9 /* kjs_domnode.h in Headers */,
+ 142011B70A003133008303F9 /* JSCSSStyleDeclaration.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
14115AFA09F847D600CA4FC1 /* NodeFilter.idl in Resources */,
14E836D309F8512000B85AE4 /* Event.idl in Resources */,
14DC0D0C09FECFA4007B0235 /* Node.idl in Resources */,
+ 142011AF0A003117008303F9 /* CSSStyleDeclaration.idl in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
93EB169509F880B00091F8FF /* WebCoreSystemInterface.mm in Sources */,
65901A4509FC6039005BD752 /* WebCoreStringTruncator.mm in Sources */,
14DC0D3709FED073007B0235 /* JSNode.cpp in Sources */,
+ 142011B60A003133008303F9 /* JSCSSStyleDeclaration.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
#include "HTMLNames.h"
#include "JSCSSPrimitiveValue.h"
#include "JSCSSRule.h"
+#include "JSCSSStyleDeclaration.h"
#include "css_base.h"
#include "css_ruleimpl.h"
#include "css_stylesheetimpl.h"
parentRule DOMCSSStyleDeclaration::ParentRule DontDelete|ReadOnly
@end
*/
-KJS_DEFINE_PROTOTYPE(DOMCSSStyleDeclarationProto)
KJS_IMPLEMENT_PROTOFUNC(DOMCSSStyleDeclarationProtoFunc)
KJS_IMPLEMENT_PROTOTYPE("DOMCSSStyleDeclaration", DOMCSSStyleDeclarationProto, DOMCSSStyleDeclarationProtoFunc)
JSValue *toJS(ExecState *exec, CSSStyleDeclaration *s)
{
- return cacheDOMObject<CSSStyleDeclaration, DOMCSSStyleDeclaration>(exec, s);
+ return cacheDOMObject<CSSStyleDeclaration, WebCore::JSCSSStyleDeclaration>(exec, s);
}
// -------------------------------------------------------------------------
class CSSStyleSheet;
class CSSValue;
class CSSValueList;
+ class JSCSSStyleDeclaration;
class MediaList;
class RectImpl;
class StyleSheet;
namespace KJS {
+ KJS_DEFINE_PROTOTYPE(DOMCSSStyleDeclarationProto)
+
class DOMCSSStyleDeclaration : public DOMObject {
public:
- DOMCSSStyleDeclaration(ExecState *exec, WebCore::CSSStyleDeclaration *s);
virtual ~DOMCSSStyleDeclaration();
virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
virtual void put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr = None);
static JSValue *indexGetter(ExecState *, JSObject *, const Identifier&, const PropertySlot&);
static JSValue *cssPropertyGetter(ExecState *, JSObject *, const Identifier&, const PropertySlot&);
+ // Don't use this class directly -- use JSCSSStyleDeclaration instead
+ friend class WebCore::JSCSSStyleDeclaration;
+ DOMCSSStyleDeclaration(ExecState *exec, WebCore::CSSStyleDeclaration *s);
+
RefPtr<WebCore::CSSStyleDeclaration> m_impl;
};
defaultStatus Window::DefaultStatus DontDelete
defaultstatus Window::DefaultStatus DontDelete
status Window::Status DontDelete
- Node Window::Node DontDelete
- Event Window::EventCtor DontDelete
- Range Window::Range DontDelete
- NodeFilter Window::NodeFilter DontDelete
DOMException Window::DOMException DontDelete
- CSSRule Window::CSSRule DontDelete
- CSSValue Window::CSSValue DontDelete
- MutationEvent Window::MutationEventCtor DontDelete
frames Window::Frames DontDelete|ReadOnly
history Window::History_ DontDelete|ReadOnly
event Window::Event_ DontDelete
return jsString(UString(m_frame->jsDefaultStatusBarText()));
case Status:
return jsString(UString(m_frame->jsStatusBarText()));
- case Node:
- return JSNode::getConstructor(exec);
- case Range:
- return JSRange::getConstructor(exec);
- case NodeFilter:
- return JSNodeFilter::getConstructor(exec);
- case DOMException:
- return getDOMExceptionConstructor(exec);
- case CSSRule:
- return JSCSSRule::getConstructor(exec);
- case CSSValue:
- return JSCSSValue::getConstructor(exec);
- case EventCtor:
- return JSEvent::getConstructor(exec);
- case MutationEventCtor:
- return JSMutationEvent::getConstructor(exec);
case Frames:
if (!frames)
frames = new FrameArray(exec, m_frame);
return retrieve(static_cast<Window*>(slot.slotBase())->m_frame->tree()->child(AtomicString(propertyName)));
}
-JSValue* Window::namedFrameGetter(ExecState*, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
-{
- // FIXME: I'm pretty sure this is wrong, because it's the same as the function above.
- // There's no point in checking for child frames twice. I suspect this should be using
- // find instead of "child". But I don't want to change the behavior without testing,
- // so I'm leaving this as-is for now.
- return retrieve(static_cast<Window*>(slot.slotBase())->m_frame->tree()->child(AtomicString(propertyName)));
-}
-
JSValue* Window::indexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot)
{
return retrieve(static_cast<Window*>(slot.slotBase())->m_frame->tree()->child(slot.index()));
return getHTMLCollection(exec, collection.get());
}
-bool Window::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
+bool Window::getOverridePropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
// we don't want any properties other than "closed" on a closed window
if (!m_frame) {
slot.setUndefined(this);
return true;
}
+
+ return false;
+}
+bool Window::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
+{
// Check for child frames by name before built-in properties to
// match Mozilla. This does not match IE, but some sites end up
// naming frames things that conflict with window properties that
slot.setCustom(this, childFrameGetter);
return true;
}
-
+
const HashEntry* entry = Lookup::findEntry(&WindowTable, propertyName);
if (entry) {
if (entry->attr & Function) {
return true;
}
- // FIXME: I'm pretty sure this is wrong, because it's the same as childFrameGetter above.
- // There's no point in checking for child frames twice. I suspect this should be using
- // find instead of "child". But I don't want to change the behavior without testing,
- // so I'm leaving this as-is for now.
- if (m_frame->tree()->child(atomicPropertyName)) {
- slot.setCustom(this, namedFrameGetter);
- return true;
- }
-
+ // FIXME: Search the whole frame hierachy somewhere around here.
+ // We need to test the correct priority order.
+
// allow window[1] or parent[1] etc. (#56983)
bool ok;
unsigned i = propertyName.toArrayIndex(&ok);
// allow shortcuts like 'Image1' instead of document.images.Image1
Document *doc = m_frame->document();
if (isSafeScript(exec) && doc && doc->isHTMLDocument()) {
+ AtomicString atomicPropertyName = propertyName;
if (static_cast<HTMLDocument*>(doc)->hasNamedItem(atomicPropertyName) || doc->getElementById(atomicPropertyName)) {
slot.setCustom(this, namedItemGetter);
return true;
static Window* retrieveActive(ExecState*);
WebCore::Frame* frame() const { return m_frame; }
virtual void mark();
- virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
+ virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+ bool getOverridePropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
JSValue *getValueProperty(ExecState *exec, int token) const;
virtual void put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr = None);
virtual bool toBoolean(ExecState*) const;
UnprotectedListenersMap jsUnprotectedEventListeners;
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
- enum { Closed, Crypto, DefaultStatus, Status, Node, EventCtor, MutationEventCtor, Range,
- NodeFilter, DOMException, CSSRule, CSSValue, Frames, History_, Event_, InnerHeight,
+ enum { Closed, Crypto, DefaultStatus, Status, DOMException, Frames, History_, Event_, InnerHeight,
InnerWidth, Length, Location_, Locationbar, Name, Navigator_, ClientInformation,
Menubar, OffscreenBuffering, Opener, OuterHeight, OuterWidth, PageXOffset, PageYOffset,
Parent, Personalbar, ScreenX, ScreenY, Scrollbars, Scroll, ScrollBy,
push(@headerContent, " static const KJS::ClassInfo info;\n");
# Constructor object getter
- if ($numConstants ne 0) {
+ if ($dataNode->extendedAttributes->{"GenerateConstructor"}) {
push(@headerContent, " static KJS::JSValue* getConstructor(KJS::ExecState*);\n")
}
push(@headerContent, "\n ");
}
- my $value = ucfirst($attribute->signature->name) . "AttrNum";
+ my $value = $attribute->signature->type =~ /Constructor$/
+ ? $attribute->signature->name . "ConstructorAttrNum"
+ : ucfirst($attribute->signature->name) . "AttrNum";
$value .= ", " if(($i < $numAttributes - 1));
$value .= ", " if(($i eq $numAttributes - 1) and ($numFunctions ne 0));
push(@headerContent, $value);
my $name = $attribute->signature->name;
push(@hashKeys, $name);
- my $value = $className . "::" . ucfirst($name) . "AttrNum";
+ my $value = $className . "::" . ($attribute->signature->type =~ /Constructor$/
+ ? $attribute->signature->name . "ConstructorAttrNum"
+ : ucfirst($attribute->signature->name) . "AttrNum");
push(@hashValues, $value);
my $special = "DontDelete";
}
$object->GenerateHashTable($hashName, $hashSize,
- \@hashKeys, \@hashValues,
- \@hashSpecials, \@hashParameters);
+ \@hashKeys, \@hashValues,
+ \@hashSpecials, \@hashParameters);
}
- # - Add all constants
my $numConstants = @{$dataNode->constants};
- if ($numConstants ne 0) {
+ my $numFunctions = @{$dataNode->functions};
+
+ # - Add all constants
+ if ($dataNode->extendedAttributes->{"GenerateConstructor"}) {
$hashSize = $numConstants;
$hashName = $className . "ConstructorTable";
@hashValues = ();
@hashSpecials = ();
@hashParameters = ();
-
+
foreach my $constant (@{$dataNode->constants}) {
my $name = $constant->name;
push(@hashKeys, $name);
-
+
my $value = "${implClassName}::$name";
push(@hashValues, $value);
-
+
my $special = "DontDelete|ReadOnly";
push(@hashSpecials, $special);
-
+
my $numParameters = 0;
push(@hashParameters, $numParameters);
}
-
+
$object->GenerateHashTable($hashName, $hashSize,
\@hashKeys, \@hashValues,
\@hashSpecials, \@hashParameters);
-
- push(@implContent, constructorFor($className, $interfaceName));
+
+ my $protoClassName;
+ if ($numFunctions ne 0 || $numConstants ne 0) {
+ $protoClassName = "${className}Proto";
+ } else {
+ # Since we have no functions or constants, we won't have generated
+ # our own prototype -- use our parent's instead
+ $protoClassName = "${parentClassName}Proto";
+ }
+
+ push(@implContent, constructorFor($className, $protoClassName, $interfaceName));
}
# - Add functions and constants to a hashtable definition
- my $numFunctions = @{$dataNode->functions};
if ($numFunctions > 0 || $numConstants > 0) {
$hashSize = $numFunctions + $numConstants;
$hashName = $className . "ProtoTable";
if ($numAttributes ne 0) {
push(@implContent, "bool ${className}::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)\n");
push(@implContent, "{\n");
+ # FIXME: We need to provide scalable hooks/attributes for this kind of extension
+ if ($interfaceName eq "DOMWindow") {
+ push(@implContent, " if (getOverridePropertySlot(exec, propertyName, slot))\n");
+ push(@implContent, " return true;\n");
+ }
push(@implContent, " return getStaticValueSlot<$className, $parentClassName>(exec, &${className}Table, this, propertyName, slot);\n");
push(@implContent, "}\n\n");
foreach my $attribute (@{$dataNode->attributes}) {
my $name = $attribute->signature->name;
-
- if (!@{$attribute->getterExceptions}) {
+
+ if ($attribute->signature->type =~ /Constructor$/) {
+ push(@implContent, " case " . $name . "ConstructorAttrNum:\n");
+ push(@implContent, " return JS" . $name . "::getConstructor(exec);\n");
+ } elsif (!@{$attribute->getterExceptions}) {
push(@implContent, " case " . ucfirst($name) . "AttrNum:\n");
push(@implContent, " return " . NativeToJSValue($attribute->signature, "impl->$name()") . ";\n");
} else {
push(@implContent, "{\n");
push(@implContent, " $implClassName* impl = static_cast<$implClassName*>(${className}::impl());\n\n");
push(@implContent, " switch (token) {\n");
-
+
foreach my $attribute (@{$dataNode->attributes}) {
if ($attribute->type !~ /^readonly/) {
my $name = $attribute->signature->name;
- push(@implContent, " case " . ucfirst($name) ."AttrNum: {\n");
- push(@implContent, " ExceptionCode ec = 0;\n") if @{$attribute->setterExceptions};
- push(@implContent, " impl->set" . ucfirst($name) . "(" . JSValueToNative($attribute->signature, "value"));
- push(@implContent, ", ec") if @{$attribute->setterExceptions};
- push(@implContent, ");\n");
- push(@implContent, " setDOMException(exec, ec);\n") if @{$attribute->setterExceptions};
- push(@implContent, " }\n");
+ if ($attribute->signature->type =~ /Constructor$/) {
+ $implIncludes{"JS" . $attribute->signature->name . ".h"} = 1;
+ push(@implContent, " case " . $name ."ConstructorAttrNum: {\n");
+ push(@implContent, " // Shadowing a built-in constructor\n");
+
+ # FIXME: We need to provide scalable hooks/attributes for this kind of extension
+ push(@implContent, " if (isSafeScript(exec))\n");
+ push(@implContent, " JSObject::put(exec, \"$name\", value);\n");
+ } else {
+ push(@implContent, " case " . ucfirst($name) ."AttrNum: {\n");
+ push(@implContent, " ExceptionCode ec = 0;\n") if @{$attribute->setterExceptions};
+ push(@implContent, " impl->set" . ucfirst($name) . "(" . JSValueToNative($attribute->signature, "value"));
+ push(@implContent, ", ec") if @{$attribute->setterExceptions};
+ push(@implContent, ");\n");
+ push(@implContent, " setDOMException(exec, ec);\n") if @{$attribute->setterExceptions};
+ }
push(@implContent, " break;\n");
+ push(@implContent, " }\n");
}
}
- push(@implContent, " }\n}\n\n");
+ push(@implContent, " }\n"); # end switch
+
+ if ($interfaceName eq "DOMWindow") {
+ push(@implContent, " // FIXME: Hack to prevent unused variable warning -- remove once DOMWindow includes a settable property\n");
+ push(@implContent, " (void)impl;\n");
+ }
+ push(@implContent, "}\n\n"); # end function
}
}
- if ($numConstants ne 0) {
+ if ($dataNode->extendedAttributes->{"GenerateConstructor"}) {
push(@implContent, "JSValue* ${className}::getConstructor(ExecState* exec)\n{\n");
push(@implContent, " return cacheGlobalObject<${className}Constructor>(exec, \"[[${interfaceName}.constructor]]\");\n");
push(@implContent, "}\n");
my $values = shift;
my $specials = shift;
my $parameters = shift;
-
+
# Helpers
my @table = ();
my @links = ();
my $maxDepth = 0;
my $collisions = 0;
- my $savedSize = $size;
+ my $numEntries = $size;
# Collect hashtable information...
my $i = 0;
foreach(@{$keys}) {
my $depth = 0;
- my $h = $object->GenerateHashValue($_) % $savedSize;
+ my $h = $object->GenerateHashValue($_) % $numEntries;
while(defined($table[$h])) {
if(defined($links[$h])) {
$i++;
}
+ if ($size eq 0) {
+ # dummy bucket -- an empty table would crash Lookup::findEntry
+ push(@implContent, " \{ 0, 0, 0, 0, 0 \}\n") ;
+ $numEntries = 1;
+ $size = 1;
+ }
push(@implContent, "};\n\n");
push(@implContent, "static const HashTable $name = \n");
- push(@implContent, "{\n 2, $size, $nameEntries, $savedSize\n};\n\n");
+ push(@implContent, "{\n 2, $size, $nameEntries, $numEntries\n};\n\n");
}
# Internal helper
sub constructorFor
{
my $className = shift;
+ my $protoClassName = shift;
my $interfaceName = shift;
my $implContent = << "EOF";
${className}Constructor(ExecState* exec)
{
setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype());
+ putDirect(prototypePropertyName, ${protoClassName}::self(exec), None);
}
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
JSValue* getValueProperty(ExecState*, int token) const;
module css {
- interface CSSPrimitiveValue : CSSValue {
+ interface [GenerateConstructor] CSSPrimitiveValue : CSSValue {
// UnitTypes
const unsigned short CSS_UNKNOWN = 0;
module css {
// Introduced in DOM Level 2:
- interface [LegacyParent=KJS::DOMCSSRule] CSSRule {
+ interface [LegacyParent=KJS::DOMCSSRule, GenerateConstructor] CSSRule {
// RuleType
const unsigned short UNKNOWN_RULE = 0;
--- /dev/null
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+module css {
+
+ // Introduced in DOM Level 2:
+ interface [LegacyParent=KJS::DOMCSSStyleDeclaration, GenerateConstructor] CSSStyleDeclaration {
+ };
+
+}
module css {
- interface [LegacyParent=KJS::DOMCSSValue] CSSValue {
+ interface [LegacyParent=KJS::DOMCSSValue, GenerateConstructor] CSSValue {
const unsigned short CSS_INHERIT = 0;
const unsigned short CSS_PRIMITIVE_VALUE = 1;
const unsigned short CSS_VALUE_LIST = 2;
module core {
- interface [LegacyParent=KJS::DOMEventTargetNode] Document : EventTargetNode {
+ interface [LegacyParent=KJS::DOMEventTargetNode, GenerateConstructor] Document : EventTargetNode {
// DOM Level 1 Core
module core {
- interface [LegacyParent=KJS::DOMEventTargetNode] Element : EventTargetNode {
+ interface [LegacyParent=KJS::DOMEventTargetNode, GenerateConstructor] Element : EventTargetNode {
// DOM Level 1 Core
module events {
// Introduced in DOM Level 2:
- interface [LegacyParent=KJS::DOMEvent] Event {
+ interface [LegacyParent=KJS::DOMEvent, GenerateConstructor] Event {
// DOM PhaseType
const unsigned short CAPTURING_PHASE = 1;
module events {
- interface MutationEvent : Event {
+ interface [GenerateConstructor] MutationEvent : Event {
// DOM Level 2
module core {
- interface [LegacyParent=KJS::DOMNode] Node {
+ interface [LegacyParent=KJS::DOMNode, GenerateConstructor] Node {
// DOM Level 2 Core
module traversal {
// Introduced in DOM Level 2:
- interface [LegacyParent=KJS::DOMNodeFilter] NodeFilter {
+ interface [LegacyParent=KJS::DOMNodeFilter, GenerateConstructor] NodeFilter {
// Constants returned by acceptNode
const short FILTER_ACCEPT = 1;
module ranges {
- interface Range {
+ interface [GenerateConstructor] Range {
// DOM Level 2
in DOMString pseudoElt,
in [ConvertUndefinedToTrue] boolean authorOnly);
+ // Global constructors
+ attribute CSSPrimitiveValueConstructor CSSPrimitiveValue;
+ attribute CSSRuleConstructor CSSRule;
+ attribute CSSStyleDeclarationConstructor CSSStyleDeclaration;
+ attribute CSSValueConstructor CSSValue;
+ attribute DocumentConstructor Document;
+ attribute ElementConstructor Element;
+ attribute EventConstructor Event;
+ attribute MutationEventConstructor MutationEvent;
+ attribute NodeConstructor Node;
+ attribute NodeFilterConstructor NodeFilter;
+ attribute RangeConstructor Range;
};
}