+2006-07-10 David Kilzer <ddkilzer@kilzer.net>
+
+ Reviewed by Darin.
+
+ - fix http://bugzilla.opendarwin.org/show_bug.cgi?id=9179
+ Implement select.options.add() method
+
+ * JavaScriptCore.exp: Added overloaded KJS::JSValue::toInt32() method.
+ * JavaScriptCore.xcodeproj/project.pbxproj: Altered attributes metadata for
+ kjs/value.h to make it available as a forwarded header.
+ * kjs/lookup.h:
+ (KJS::lookupPut): Extracted a lookupPut() method from the existing lookupPut() method.
+ The new method returns a boolean value if no entry is found in the lookup table.
+ * kjs/value.cpp:
+ (KJS::JSValue::toInt32): Overloaded toInt32() method with boolean "Ok" argument.
+ * kjs/value.h: Ditto.
+
2006-07-10 Geoffrey Garen <ggaren@apple.com>
No review necessary. Removed bogus file I accidentally checked in before.
__ZNK3KJS6JSCell9getStringEv
__ZNK3KJS6JSCell9getUInt32ERj
__ZNK3KJS7JSValue7toInt32EPNS_9ExecStateE
+__ZNK3KJS7JSValue7toInt32EPNS_9ExecStateERb
__ZNK3KJS7JSValue8toUInt32EPNS_9ExecStateE
__ZNK3KJS7JSValue9toIntegerEPNS_9ExecStateE
__ZNK3KJS7UString10UTF8StringEv
932F5B510822A1C700736975 /* number_object.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8710255597D01FF60F7 /* number_object.h */; settings = {ATTRIBUTES = (Private, ); }; };
932F5B530822A1C700736975 /* object_object.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8740255597D01FF60F7 /* object_object.h */; settings = {ATTRIBUTES = (Private, ); }; };
932F5B540822A1C700736975 /* object.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8760255597D01FF60F7 /* object.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 932F5B550822A1C700736975 /* operations.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8780255597D01FF60F7 /* operations.h */; };
+ 932F5B550822A1C700736975 /* operations.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8780255597D01FF60F7 /* operations.h */; settings = {ATTRIBUTES = (Private, ); }; };
932F5B560822A1C700736975 /* property_map.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A87A0255597D01FF60F7 /* property_map.h */; settings = {ATTRIBUTES = (Private, ); }; };
932F5B570822A1C700736975 /* regexp_object.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A87C0255597D01FF60F7 /* regexp_object.h */; settings = {ATTRIBUTES = (Private, ); }; };
932F5B580822A1C700736975 /* regexp.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A87E0255597D01FF60F7 /* regexp.h */; settings = {ATTRIBUTES = (Private, ); }; };
/**
* This one is for "put".
- * Lookup hash entry for property to be set, and set the value.
+ * It looks up a hash entry for the property to be set. If an entry
+ * is found it sets the value and returns true, else it returns false.
*/
- template <class ThisImp, class ParentImp>
- inline void lookupPut(ExecState *exec, const Identifier &propertyName,
- JSValue *value, int attr,
+ template <class ThisImp>
+ inline bool lookupPut(ExecState* exec, const Identifier &propertyName,
+ JSValue* value, int attr,
const HashTable* table, ThisImp* thisObj)
{
const HashEntry* entry = Lookup::findEntry(table, propertyName);
- if (!entry) // not found: forward to parent
- thisObj->ParentImp::put(exec, propertyName, value, attr);
- else if (entry->attr & Function) // function: put as override property
+ if (!entry)
+ return false;
+
+ if (entry->attr & Function) // function: put as override property
thisObj->JSObject::put(exec, propertyName, value, attr);
else if (entry->attr & ReadOnly) // readonly! Can't put!
#ifdef KJS_VERBOSE
#endif
else
thisObj->putValueProperty(exec, entry->value, value, attr);
+
+ return true;
+ }
+
+ /**
+ * This one is for "put".
+ * It calls lookupPut<ThisImp>() to set the value. If that call
+ * returns false (meaning no entry in the hash table was found),
+ * then it calls put() on the ParentImp class.
+ */
+ template <class ThisImp, class ParentImp>
+ inline void lookupPut(ExecState* exec, const Identifier &propertyName,
+ JSValue* value, int attr,
+ const HashTable* table, ThisImp* thisObj)
+ {
+ if (!lookupPut<ThisImp>(exec, propertyName, value, attr, table, thisObj))
+ thisObj->ParentImp::put(exec, propertyName, value, attr); // not found: forward to parent
}
} // namespace
return roundValue(exec, const_cast<JSValue*>(this));
}
-int32_t JSValue::toInt32(ExecState *exec) const
+int32_t JSValue::toInt32(ExecState* exec, bool& ok) const
{
+ ok = true;
+
uint32_t i;
if (getUInt32(i))
return i;
double d = roundValue(exec, const_cast<JSValue*>(this));
- if (isNaN(d) || isInf(d))
+ if (isNaN(d) || isInf(d)) {
+ ok = false;
return 0;
+ }
double d32 = fmod(d, D32);
if (d32 >= D32 / 2)
// Integer conversions.
double toInteger(ExecState *exec) const;
- int32_t toInt32(ExecState *exec) const;
+ int32_t toInt32(ExecState*) const;
+ int32_t toInt32(ExecState*, bool& Ok) const;
uint32_t toUInt32(ExecState *exec) const;
uint16_t toUInt16(ExecState *exec) const;
return JSImmediate::isImmediate(this) ? JSImmediate::toBoolean(this) : downcast()->toBoolean(exec);
}
+inline int32_t JSValue::toInt32(ExecState* exec) const
+{
+ bool ignored;
+ return toInt32(exec, ignored);
+}
+
inline double JSValue::toNumber(ExecState *exec) const
{
return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : downcast()->toNumber(exec);
+2006-07-10 David Kilzer <ddkilzer@kilzer.net>
+
+ Reviewed by Darin.
+
+ - test for http://bugzilla.opendarwin.org/show_bug.cgi?id=9179
+ Implement select.options.add() method
+
+ * fast/dom/select-selectedIndex-multiple-expected.txt: Updated test results.
+ * fast/dom/select-selectedIndex-multiple.html: Updated to print comments between
+ tests to make failures easier to track down.
+ * fast/dom/select-selectedIndex-expected.txt: Mirrored updates from select-selectedIndex-multiple.html
+ * fast/dom/select-selectedIndex.html: Ditto.
+ * fast/js/resources/select-options-add.js: Added.
+ * fast/js/select-options-add-expected.txt: Added.
+ * fast/js/select-options-add.html: Added.
+
2006-07-10 Adele Peterson <adele@apple.com>
Reviewed by Beth.
+1) setting length to a negative length
+PASS mySelect.options.length = -1; threw exception Error: INDEX_SIZE_ERR: DOM Exception 1.
PASS mySelect.options.length is 2
PASS mySelect.selectedIndex is 1
+2) setting length to a larger length
PASS mySelect.options.length is 5
PASS mySelect.selectedIndex is 1
+3) setting length to a smaller length
PASS mySelect.options.length is 2
PASS mySelect.selectedIndex is 1
PASS mySelect.options.length is 1
PASS mySelect.selectedIndex is -1
+4) setting length to the same length
PASS mySelect.options.length is 2
PASS mySelect.selectedIndex is 1
+5) setting length to non-integer value: null
PASS mySelect.options.length is 0
PASS mySelect.selectedIndex is -1
+6) setting length to non-integer value: undefined
PASS mySelect.options.length is 0
PASS mySelect.selectedIndex is -1
+7) setting length to non-integer value: non-numeric string
PASS mySelect.options.length is 0
PASS mySelect.selectedIndex is -1
+8) setting length to non-integer value: object
+PASS mySelect.options.length is 0
+PASS mySelect.selectedIndex is -1
+9) setting length to non-integer value: negative infinity
+PASS mySelect.options.length is 0
+PASS mySelect.selectedIndex is -1
+10) setting length to non-integer value: NaN
+PASS mySelect.options.length is 0
+PASS mySelect.selectedIndex is -1
+11) setting length to non-integer value: positive infinity
+PASS mySelect.options.length is 0
+PASS mySelect.selectedIndex is -1
+12) setting length to non-integer value: floating point number
PASS mySelect.options.length is 2
PASS mySelect.selectedIndex is 1
+13) setting an element by index past the end of the current list
PASS mySelect.options.length is 11
PASS mySelect.selectedIndex is 10
+14) setting an existing element by index
PASS mySelect.options.length is 11
PASS mySelect.selectedIndex is 10
+15) trying to set an element that's not an option: null
PASS mySelect.options.length is 10
PASS mySelect.selectedIndex is -1
+16) trying to set an element that's not an option: undefined
PASS mySelect.options.length is 10
PASS mySelect.selectedIndex is -1
+17) trying to set an element that's not an option: select element
+PASS mySelect.options[10] = mySelect; threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
PASS mySelect.options.length is 10
PASS mySelect.selectedIndex is -1
+18) trying to set a option element using an invalid index: negative infinity
+PASS mySelect.options.length is 10
+PASS mySelect.selectedIndex is -1
+19) trying to set a option element using an invalid index: NaN
+PASS mySelect.options.length is 10
+PASS mySelect.selectedIndex is -1
+20) trying to set a option element using an invalid index: positive infinity
+PASS mySelect.options.length is 10
+PASS mySelect.selectedIndex is -1
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+1) setting length to a negative length
+PASS mySelect.options.length = -1; threw exception Error: INDEX_SIZE_ERR: DOM Exception 1.
PASS mySelect.options.length is 2
PASS mySelect.selectedIndex is 0
+2) setting length to a larger length
PASS mySelect.options.length is 5
PASS mySelect.selectedIndex is 0
+3) setting length to a smaller length
PASS mySelect.options.length is 2
PASS mySelect.selectedIndex is 0
PASS mySelect.options.length is 1
PASS mySelect.selectedIndex is 0
+4) setting length to the same length
PASS mySelect.options.length is 2
PASS mySelect.selectedIndex is 0
+5) setting length to non-integer value: null
PASS mySelect.options.length is 0
PASS mySelect.selectedIndex is -1
+6) setting length to non-integer value: undefined
PASS mySelect.options.length is 0
PASS mySelect.selectedIndex is -1
+7) setting length to non-integer value: non-numeric string
PASS mySelect.options.length is 0
PASS mySelect.selectedIndex is -1
+8) setting length to non-integer value: object
+PASS mySelect.options.length is 0
+PASS mySelect.selectedIndex is -1
+9) setting length to non-integer value: negative infinity
+PASS mySelect.options.length is 0
+PASS mySelect.selectedIndex is -1
+10) setting length to non-integer value: NaN
+PASS mySelect.options.length is 0
+PASS mySelect.selectedIndex is -1
+11) setting length to non-integer value: positive infinity
+PASS mySelect.options.length is 0
+PASS mySelect.selectedIndex is -1
+12) setting length to non-integer value: floating point number
PASS mySelect.options.length is 2
PASS mySelect.selectedIndex is 0
+13) setting an element by index past the end of the current list
PASS mySelect.options.length is 11
PASS mySelect.selectedIndex is 0
+14) setting an existing element by index
PASS mySelect.options.length is 11
PASS mySelect.selectedIndex is 0
+15) trying to set an element that's not an option: null
PASS mySelect.options.length is 10
PASS mySelect.selectedIndex is 0
+16) trying to set an element that's not an option: undefined
PASS mySelect.options.length is 10
PASS mySelect.selectedIndex is 0
+17) trying to set an element that's not an option: select element
+PASS mySelect.options[10] = mySelect; threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
PASS mySelect.options.length is 10
PASS mySelect.selectedIndex is 0
+18) trying to set a option element using an invalid index: negative infinity
+PASS mySelect.options.length is 10
+PASS mySelect.selectedIndex is 0
+19) trying to set a option element using an invalid index: NaN
+PASS mySelect.options.length is 10
+PASS mySelect.selectedIndex is 0
+20) trying to set a option element using an invalid index: positive infinity
+PASS mySelect.options.length is 10
+PASS mySelect.selectedIndex is 0
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
<select multiple id="test" size="3">
</select>
<div id="console"></div>
var mySelect = document.getElementById("test");
reset(mySelect);
+var i = 0;
-mySelect.options.length = -1;
+debug((++i) + ") setting length to a negative length");
+shouldThrow("mySelect.options.length = -1;");
shouldBe("mySelect.options.length", "2");
shouldBe("mySelect.selectedIndex", "0");
-// 1) setting length to a larger length
+debug((++i) + ") setting length to a larger length");
mySelect.options.length = 5;
shouldBe("mySelect.options.length", "5");
shouldBe("mySelect.selectedIndex", "0");
-// 2) setting length to a smaller length
+debug((++i) + ") setting length to a smaller length");
mySelect.options.length = 2;
shouldBe("mySelect.options.length", "2");
shouldBe("mySelect.selectedIndex", "0");
shouldBe("mySelect.selectedIndex", "0");
reset(mySelect);
-// 3) setting length to the same length
+debug((++i) + ") setting length to the same length");
mySelect.options.length = 2;
shouldBe("mySelect.options.length", "2");
shouldBe("mySelect.selectedIndex", "0");
-// 4) setting length to non-integer values (null,
-// undefined, non-numeric string, floating point number)
+debug((++i) + ") setting length to non-integer value: null");
mySelect.options.length = null;
shouldBe("mySelect.options.length", "0");
shouldBe("mySelect.selectedIndex", "-1");
reset(mySelect);
+debug((++i) + ") setting length to non-integer value: undefined");
mySelect.options.length = undefined;
shouldBe("mySelect.options.length", "0");
shouldBe("mySelect.selectedIndex", "-1");
reset(mySelect);
+debug((++i) + ") setting length to non-integer value: non-numeric string");
mySelect.options.length = "apple";
shouldBe("mySelect.options.length", "0");
shouldBe("mySelect.selectedIndex", "-1");
reset(mySelect);
+debug((++i) + ") setting length to non-integer value: object");
+mySelect.options.length = new Object();
+shouldBe("mySelect.options.length", "0");
+shouldBe("mySelect.selectedIndex", "-1");
+reset(mySelect);
+
+debug((++i) + ") setting length to non-integer value: negative infinity");
+mySelect.options.length = -1/0;
+shouldBe("mySelect.options.length", "0");
+shouldBe("mySelect.selectedIndex", "-1");
+reset(mySelect);
+
+debug((++i) + ") setting length to non-integer value: NaN");
+mySelect.options.length = 0/0;
+shouldBe("mySelect.options.length", "0");
+shouldBe("mySelect.selectedIndex", "-1");
+reset(mySelect);
+
+debug((++i) + ") setting length to non-integer value: positive infinity");
+mySelect.options.length = 1/0;
+shouldBe("mySelect.options.length", "0");
+shouldBe("mySelect.selectedIndex", "-1");
+reset(mySelect);
+
+debug((++i) + ") setting length to non-integer value: floating point number");
mySelect.options.length = 2.1;
shouldBe("mySelect.options.length", "2");
shouldBe("mySelect.selectedIndex", "0");
-// 5) setting an element by index past the end of the current list
+debug((++i) + ") setting an element by index past the end of the current list");
mySelect.options[10] = new Option("ten", "value", true, true);
shouldBe("mySelect.options.length", "11");
shouldBe("mySelect.selectedIndex", "0");
-// 6) setting an existing element by index
+debug((++i) + ") setting an existing element by index");
mySelect.options[10] = mySelect.options[10];
shouldBe("mySelect.options.length", "11");
shouldBe("mySelect.selectedIndex", "0");
-// 7) trying to set an element that's not an option
-// element (null, undefined, other kinds of objects, other kinds of elements)
+debug((++i) + ") trying to set an element that's not an option: null");
mySelect.options[10] = null;
shouldBe("mySelect.options.length", "10");
shouldBe("mySelect.selectedIndex", "0");
+
+debug((++i) + ") trying to set an element that's not an option: undefined");
mySelect.options[10] = undefined;
shouldBe("mySelect.options.length", "10");
shouldBe("mySelect.selectedIndex", "0");
-mySelect.options[10] = mySelect;
+
+debug((++i) + ") trying to set an element that's not an option: select element");
+shouldThrow("mySelect.options[10] = mySelect;");
shouldBe("mySelect.options.length", "10");
shouldBe("mySelect.selectedIndex", "0");
-</script>
+debug((++i) + ") trying to set a option element using an invalid index: negative infinity");
+mySelect.options[-1/0] = document.createElement("option");
+shouldBe("mySelect.options.length", "10");
+shouldBe("mySelect.selectedIndex", "0");
+debug((++i) + ") trying to set a option element using an invalid index: NaN");
+mySelect.options[0/0] = document.createElement("option");
+shouldBe("mySelect.options.length", "10");
+shouldBe("mySelect.selectedIndex", "0");
+
+debug((++i) + ") trying to set a option element using an invalid index: positive infinity");
+mySelect.options[1/0] = document.createElement("option");
+shouldBe("mySelect.options.length", "10");
+shouldBe("mySelect.selectedIndex", "0");
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../js/resources/js-test-post.js"></script>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
<select id="test" size="3">
</select>
<div id="console"></div>
var mySelect = document.getElementById("test");
reset(mySelect);
+var i = 0;
-mySelect.options.length = -1;
+debug((++i) + ") setting length to a negative length");
+shouldThrow("mySelect.options.length = -1;");
shouldBe("mySelect.options.length", "2");
shouldBe("mySelect.selectedIndex", "1");
-// 1) setting length to a larger length
+debug((++i) + ") setting length to a larger length");
mySelect.options.length = 5;
shouldBe("mySelect.options.length", "5");
shouldBe("mySelect.selectedIndex", "1");
-// 2) setting length to a smaller length
+debug((++i) + ") setting length to a smaller length");
mySelect.options.length = 2;
shouldBe("mySelect.options.length", "2");
shouldBe("mySelect.selectedIndex", "1");
shouldBe("mySelect.selectedIndex", "-1");
reset(mySelect);
-// 3) setting length to the same length
+debug((++i) + ") setting length to the same length");
mySelect.options.length = 2;
shouldBe("mySelect.options.length", "2");
shouldBe("mySelect.selectedIndex", "1");
-// 4) setting length to non-integer values (null,
-// undefined, non-numeric string, floating point number)
+debug((++i) + ") setting length to non-integer value: null");
mySelect.options.length = null;
shouldBe("mySelect.options.length", "0");
shouldBe("mySelect.selectedIndex", "-1");
reset(mySelect);
+debug((++i) + ") setting length to non-integer value: undefined");
mySelect.options.length = undefined;
shouldBe("mySelect.options.length", "0");
shouldBe("mySelect.selectedIndex", "-1");
reset(mySelect);
+debug((++i) + ") setting length to non-integer value: non-numeric string");
mySelect.options.length = "apple";
shouldBe("mySelect.options.length", "0");
shouldBe("mySelect.selectedIndex", "-1");
reset(mySelect);
+debug((++i) + ") setting length to non-integer value: object");
+mySelect.options.length = new Object();
+shouldBe("mySelect.options.length", "0");
+shouldBe("mySelect.selectedIndex", "-1");
+reset(mySelect);
+
+debug((++i) + ") setting length to non-integer value: negative infinity");
+mySelect.options.length = -1/0;
+shouldBe("mySelect.options.length", "0");
+shouldBe("mySelect.selectedIndex", "-1");
+reset(mySelect);
+
+debug((++i) + ") setting length to non-integer value: NaN");
+mySelect.options.length = 0/0;
+shouldBe("mySelect.options.length", "0");
+shouldBe("mySelect.selectedIndex", "-1");
+reset(mySelect);
+
+debug((++i) + ") setting length to non-integer value: positive infinity");
+mySelect.options.length = 1/0;
+shouldBe("mySelect.options.length", "0");
+shouldBe("mySelect.selectedIndex", "-1");
+reset(mySelect);
+
+debug((++i) + ") setting length to non-integer value: floating point number");
mySelect.options.length = 2.1;
shouldBe("mySelect.options.length", "2");
shouldBe("mySelect.selectedIndex", "1");
-// 5) setting an element by index past the end of the current list
+debug((++i) + ") setting an element by index past the end of the current list");
mySelect.options[10] = new Option("ten", "value", true, true);
shouldBe("mySelect.options.length", "11");
shouldBe("mySelect.selectedIndex", "10");
-// 6) setting an existing element by index
+debug((++i) + ") setting an existing element by index");
mySelect.options[10] = mySelect.options[10];
shouldBe("mySelect.options.length", "11");
shouldBe("mySelect.selectedIndex", "10");
-// 7) trying to set an element that's not an option
-// element (null, undefined, other kinds of objects, other kinds of elements)
+debug((++i) + ") trying to set an element that's not an option: null");
mySelect.options[10] = null;
shouldBe("mySelect.options.length", "10");
shouldBe("mySelect.selectedIndex", "-1");
+
+debug((++i) + ") trying to set an element that's not an option: undefined");
mySelect.options[10] = undefined;
shouldBe("mySelect.options.length", "10");
shouldBe("mySelect.selectedIndex", "-1");
-mySelect.options[10] = mySelect;
+
+debug((++i) + ") trying to set an element that's not an option: select element");
+shouldThrow("mySelect.options[10] = mySelect;");
+shouldBe("mySelect.options.length", "10");
+shouldBe("mySelect.selectedIndex", "-1");
+
+debug((++i) + ") trying to set a option element using an invalid index: negative infinity");
+mySelect.options[-1/0] = document.createElement("option");
+shouldBe("mySelect.options.length", "10");
+shouldBe("mySelect.selectedIndex", "-1");
+
+debug((++i) + ") trying to set a option element using an invalid index: NaN");
+mySelect.options[0/0] = document.createElement("option");
+shouldBe("mySelect.options.length", "10");
+shouldBe("mySelect.selectedIndex", "-1");
+
+debug((++i) + ") trying to set a option element using an invalid index: positive infinity");
+mySelect.options[1/0] = document.createElement("option");
shouldBe("mySelect.options.length", "10");
shouldBe("mySelect.selectedIndex", "-1");
+debug("");
+var successfullyParsed = true;
</script>
+<script src="../js/resources/js-test-post.js"></script>
--- /dev/null
+description(
+"This test checks the behavior of the add() method on the select.options object.<br>" +
+"It covers both the the one-argument (1.x) and two-argument (2.x) signatures of the add() method."
+);
+
+debug("1.1 Add Option to empty Options");
+var select1 = document.getElementById("select1");
+var option1 = document.createElement("OPTION");
+select1.options.add(option1);
+option1.value = "1";
+option1.textContent = "A";
+shouldBe("select1.options.length", "1");
+shouldBe("select1.selectedIndex", "0");
+shouldBe("select1.options[0].value", "'1'");
+shouldBe("select1.options[0].textContent", "'A'");
+debug("");
+
+debug("1.2 Add Option to non-empty Options");
+option1 = document.createElement("OPTION");
+select1.options.add(option1);
+option1.value = "2";
+option1.textContent = "B";
+shouldBe("select1.options.length", "2");
+shouldBe("select1.selectedIndex", "0");
+shouldBe("select1.options[0].value", "'1'");
+shouldBe("select1.options[0].textContent", "'A'");
+shouldBe("select1.options[1].value", "'2'");
+shouldBe("select1.options[1].textContent", "'B'");
+debug("");
+
+debug("1.3 Add Option after setting parameters");
+option1 = document.createElement("OPTION");
+option1.value = "3";
+option1.textContent = "C";
+select1.options.add(option1);
+shouldBe("select1.options.length", "3");
+shouldBe("select1.selectedIndex", "0");
+shouldBe("select1.options[0].value", "'1'");
+shouldBe("select1.options[0].textContent", "'A'");
+shouldBe("select1.options[1].value", "'2'");
+shouldBe("select1.options[1].textContent", "'B'");
+shouldBe("select1.options[2].value", "'3'");
+shouldBe("select1.options[2].textContent", "'C'");
+debug("");
+
+debug("1.4 Add a non-Option element");
+option1 = document.createElement("DIV");
+shouldThrow("select1.options.add(option1)");
+shouldBe("select1.options.length", "3");
+shouldBe("select1.selectedIndex", "0");
+debug("");
+
+debug("1.5 Add a non-element (string)");
+option1 = "o";
+shouldThrow("select1.options.add(option1)");
+shouldBe("select1.options.length", "3");
+shouldBe("select1.selectedIndex", "0");
+debug("");
+
+debug("1.6 Add a non-element (number)");
+option1 = 3.14;
+shouldThrow("select1.options.add(option1)");
+shouldBe("select1.options.length", "3");
+shouldBe("select1.selectedIndex", "0");
+debug("");
+
+debug("1.7 Add undefined");
+option1 = undefined;
+shouldThrow("select1.options.add(option1)");
+shouldBe("select1.options.length", "3");
+shouldBe("select1.selectedIndex", "0");
+debug("");
+
+debug("1.8 Add null");
+option1 = null;
+shouldThrow("select1.options.add(option1)");
+shouldBe("select1.options.length", "3");
+shouldBe("select1.selectedIndex", "0");
+debug("");
+
+debug("1.9 Add negative infinity");
+option1 = -1/0;
+shouldThrow("select1.options.add(option1)");
+shouldBe("select1.options.length", "3");
+shouldBe("select1.selectedIndex", "0");
+debug("");
+
+debug("1.10 Add NaN");
+option1 = 0/0;
+shouldThrow("select1.options.add(option1)");
+shouldBe("select1.options.length", "3");
+shouldBe("select1.selectedIndex", "0");
+debug("");
+
+debug("1.11 Add positive infinity");
+option1 = 1/0;
+shouldThrow("select1.options.add(option1)");
+shouldBe("select1.options.length", "3");
+shouldBe("select1.selectedIndex", "0");
+debug("");
+
+debug("2.1 Add Option to empty Options");
+var select2 = document.getElementById("select2");
+var option2 = document.createElement("OPTION");
+select2.options.add(option2, 0);
+option2.value = "1";
+option2.textContent = "A";
+shouldBe("select2.options.length", "1");
+shouldBe("select2.selectedIndex", "0");
+shouldBe("select2.options[0].value", "'1'");
+shouldBe("select2.options[0].textContent", "'A'");
+debug("");
+
+debug("2.2 Add Option after setting parameters");
+option2 = document.createElement("OPTION");
+option2.value = "2";
+option2.textContent = "B";
+select2.options.add(option2, 1);
+shouldBe("select2.options.length", "2");
+shouldBe("select2.selectedIndex", "0");
+shouldBe("select2.options[0].value", "'1'");
+shouldBe("select2.options[0].textContent", "'A'");
+shouldBe("select2.options[1].value", "'2'");
+shouldBe("select2.options[1].textContent", "'B'");
+debug("");
+
+debug("2.3 Insert Option at beginning of Options");
+option2 = document.createElement("OPTION");
+select2.options.add(option2, 0);
+option2.value = "0";
+option2.textContent = "Z";
+shouldBe("select2.options.length", "3");
+shouldBe("select2.selectedIndex", "1");
+shouldBe("select2.options[0].value", "'0'");
+shouldBe("select2.options[0].textContent", "'Z'");
+shouldBe("select2.options[1].value", "'1'");
+shouldBe("select2.options[1].textContent", "'A'");
+shouldBe("select2.options[2].value", "'2'");
+shouldBe("select2.options[2].textContent", "'B'");
+debug("");
+
+debug("2.4 Insert Option in middle of Options");
+option2 = document.createElement("OPTION");
+select2.options.add(option2, 2);
+option2.value = "1.5";
+option2.textContent = "A.5";
+shouldBe("select2.options.length", "4");
+shouldBe("select2.selectedIndex", "1");
+shouldBe("select2.options[0].value", "'0'");
+shouldBe("select2.options[0].textContent", "'Z'");
+shouldBe("select2.options[1].value", "'1'");
+shouldBe("select2.options[1].textContent", "'A'");
+shouldBe("select2.options[2].value", "'1.5'");
+shouldBe("select2.options[2].textContent", "'A.5'");
+shouldBe("select2.options[3].value", "'2'");
+shouldBe("select2.options[3].textContent", "'B'");
+debug("");
+
+debug("2.5 Insert Option at end of Options");
+option2 = document.createElement("OPTION");
+select2.options.add(option2, 4);
+option2.value = "3";
+option2.textContent = "C";
+shouldBe("select2.options.length", "5");
+shouldBe("select2.selectedIndex", "1");
+shouldBe("select2.options[0].value", "'0'");
+shouldBe("select2.options[0].textContent", "'Z'");
+shouldBe("select2.options[1].value", "'1'");
+shouldBe("select2.options[1].textContent", "'A'");
+shouldBe("select2.options[2].value", "'1.5'");
+shouldBe("select2.options[2].textContent", "'A.5'");
+shouldBe("select2.options[3].value", "'2'");
+shouldBe("select2.options[3].textContent", "'B'");
+shouldBe("select2.options[4].value", "'3'");
+shouldBe("select2.options[4].textContent", "'C'");
+debug("");
+
+debug("2.6 Insert Option beyond the end of Options");
+option2 = document.createElement("OPTION");
+select2.options.add(option2, 6);
+option2.value = "4";
+option2.textContent = "D";
+shouldBe("select2.options.length", "6");
+shouldBe("select2.selectedIndex", "1");
+shouldBe("select2.options[0].value", "'0'");
+shouldBe("select2.options[0].textContent", "'Z'");
+shouldBe("select2.options[1].value", "'1'");
+shouldBe("select2.options[1].textContent", "'A'");
+shouldBe("select2.options[2].value", "'1.5'");
+shouldBe("select2.options[2].textContent", "'A.5'");
+shouldBe("select2.options[3].value", "'2'");
+shouldBe("select2.options[3].textContent", "'B'");
+shouldBe("select2.options[4].value", "'3'");
+shouldBe("select2.options[4].textContent", "'C'");
+shouldBe("select2.options[5].value", "'4'");
+shouldBe("select2.options[5].textContent", "'D'");
+debug("");
+
+debug("2.7 Add an Option at index -1");
+option2 = document.createElement("OPTION");
+select2.options.add(option2, -1);
+option2.value = "5";
+option2.textContent = "E";
+shouldBe("select2.options.length", "7");
+shouldBe("select2.selectedIndex", "1");
+shouldBe("select2.options[0].value", "'0'");
+shouldBe("select2.options[0].textContent", "'Z'");
+shouldBe("select2.options[1].value", "'1'");
+shouldBe("select2.options[1].textContent", "'A'");
+shouldBe("select2.options[2].value", "'1.5'");
+shouldBe("select2.options[2].textContent", "'A.5'");
+shouldBe("select2.options[3].value", "'2'");
+shouldBe("select2.options[3].textContent", "'B'");
+shouldBe("select2.options[4].value", "'3'");
+shouldBe("select2.options[4].textContent", "'C'");
+shouldBe("select2.options[5].value", "'4'");
+shouldBe("select2.options[5].textContent", "'D'");
+shouldBe("select2.options[6].value", "'5'");
+shouldBe("select2.options[6].textContent", "'E'");
+debug("");
+
+debug("2.8 Add an Option at index -2");
+option2 = document.createElement("OPTION");
+shouldThrow("select2.options.add(option2, -2)");
+shouldBe("select2.options.length", "7");
+shouldBe("select2.selectedIndex", "1");
+debug("");
+
+debug("2.9 Add an Option at index -Infinity");
+option2 = document.createElement("OPTION");
+shouldThrow("select2.options.add(option2, -1/0)");
+shouldBe("select2.options.length", "7");
+shouldBe("select2.selectedIndex", "1");
+debug("");
+
+debug("2.10 Add an Option at index NaN");
+option2 = document.createElement("OPTION");
+shouldThrow("select2.options.add(option2, 0/0)");
+shouldBe("select2.options.length", "7");
+shouldBe("select2.selectedIndex", "1");
+debug("");
+
+debug("2.11 Add an Option at index Infinity");
+option2 = document.createElement("OPTION");
+shouldThrow("select2.options.add(option2, 1/0)");
+shouldBe("select2.options.length", "7");
+shouldBe("select2.selectedIndex", "1");
+debug("");
+
+debug("2.12 Add a non-Option element");
+option2 = document.createElement("DIV");
+shouldThrow("select2.options.add(option2, 1)");
+shouldBe("select2.options.length", "7");
+shouldBe("select2.selectedIndex", "1");
+debug("");
+
+debug("2.13 Add a non-element (string)");
+option2 = "o";
+shouldThrow("select2.options.add(option2, 1)");
+shouldBe("select2.options.length", "7");
+shouldBe("select2.selectedIndex", "1");
+debug("");
+
+debug("2.14 Add a non-element (number)");
+option2 = 3.14;
+shouldThrow("select2.options.add(option2, 1)");
+shouldBe("select2.options.length", "7");
+shouldBe("select2.selectedIndex", "1");
+debug("");
+
+debug("2.15 Add undefined");
+option2 = undefined;
+shouldThrow("select2.options.add(option2, 1)");
+shouldBe("select2.options.length", "7");
+shouldBe("select2.selectedIndex", "1");
+debug("");
+
+debug("2.16 Add null");
+option2 = null;
+shouldThrow("select2.options.add(option2, 1)");
+shouldBe("select2.options.length", "7");
+shouldBe("select2.selectedIndex", "1");
+debug("");
+
+debug("2.17 Add negative infinity");
+option2 = -1/0;
+shouldThrow("select2.options.add(option2, 1)");
+shouldBe("select2.options.length", "7");
+shouldBe("select2.selectedIndex", "1");
+debug("");
+
+debug("2.18 Add NaN");
+option2 = 0/0;
+shouldThrow("select2.options.add(option2, 1)");
+shouldBe("select2.options.length", "7");
+shouldBe("select2.selectedIndex", "1");
+debug("");
+
+debug("2.19 Add positive infinity");
+option2 = 1/0;
+shouldThrow("select2.options.add(option2, 1)");
+shouldBe("select2.options.length", "7");
+shouldBe("select2.selectedIndex", "1");
+debug("");
+
+successfullyParsed = true;
--- /dev/null
+This test checks the behavior of the add() method on the select.options object.
+It covers both the the one-argument (1.x) and two-argument (2.x) signatures of the add() method.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+1.1 Add Option to empty Options
+PASS select1.options.length is 1
+PASS select1.selectedIndex is 0
+PASS select1.options[0].value is '1'
+PASS select1.options[0].textContent is 'A'
+
+1.2 Add Option to non-empty Options
+PASS select1.options.length is 2
+PASS select1.selectedIndex is 0
+PASS select1.options[0].value is '1'
+PASS select1.options[0].textContent is 'A'
+PASS select1.options[1].value is '2'
+PASS select1.options[1].textContent is 'B'
+
+1.3 Add Option after setting parameters
+PASS select1.options.length is 3
+PASS select1.selectedIndex is 0
+PASS select1.options[0].value is '1'
+PASS select1.options[0].textContent is 'A'
+PASS select1.options[1].value is '2'
+PASS select1.options[1].textContent is 'B'
+PASS select1.options[2].value is '3'
+PASS select1.options[2].textContent is 'C'
+
+1.4 Add a non-Option element
+PASS select1.options.add(option1) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS select1.options.length is 3
+PASS select1.selectedIndex is 0
+
+1.5 Add a non-element (string)
+PASS select1.options.add(option1) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS select1.options.length is 3
+PASS select1.selectedIndex is 0
+
+1.6 Add a non-element (number)
+PASS select1.options.add(option1) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS select1.options.length is 3
+PASS select1.selectedIndex is 0
+
+1.7 Add undefined
+PASS select1.options.add(option1) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS select1.options.length is 3
+PASS select1.selectedIndex is 0
+
+1.8 Add null
+PASS select1.options.add(option1) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS select1.options.length is 3
+PASS select1.selectedIndex is 0
+
+1.9 Add negative infinity
+PASS select1.options.add(option1) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS select1.options.length is 3
+PASS select1.selectedIndex is 0
+
+1.10 Add NaN
+PASS select1.options.add(option1) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS select1.options.length is 3
+PASS select1.selectedIndex is 0
+
+1.11 Add positive infinity
+PASS select1.options.add(option1) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS select1.options.length is 3
+PASS select1.selectedIndex is 0
+
+2.1 Add Option to empty Options
+PASS select2.options.length is 1
+PASS select2.selectedIndex is 0
+PASS select2.options[0].value is '1'
+PASS select2.options[0].textContent is 'A'
+
+2.2 Add Option after setting parameters
+PASS select2.options.length is 2
+PASS select2.selectedIndex is 0
+PASS select2.options[0].value is '1'
+PASS select2.options[0].textContent is 'A'
+PASS select2.options[1].value is '2'
+PASS select2.options[1].textContent is 'B'
+
+2.3 Insert Option at beginning of Options
+PASS select2.options.length is 3
+PASS select2.selectedIndex is 1
+PASS select2.options[0].value is '0'
+PASS select2.options[0].textContent is 'Z'
+PASS select2.options[1].value is '1'
+PASS select2.options[1].textContent is 'A'
+PASS select2.options[2].value is '2'
+PASS select2.options[2].textContent is 'B'
+
+2.4 Insert Option in middle of Options
+PASS select2.options.length is 4
+PASS select2.selectedIndex is 1
+PASS select2.options[0].value is '0'
+PASS select2.options[0].textContent is 'Z'
+PASS select2.options[1].value is '1'
+PASS select2.options[1].textContent is 'A'
+PASS select2.options[2].value is '1.5'
+PASS select2.options[2].textContent is 'A.5'
+PASS select2.options[3].value is '2'
+PASS select2.options[3].textContent is 'B'
+
+2.5 Insert Option at end of Options
+PASS select2.options.length is 5
+PASS select2.selectedIndex is 1
+PASS select2.options[0].value is '0'
+PASS select2.options[0].textContent is 'Z'
+PASS select2.options[1].value is '1'
+PASS select2.options[1].textContent is 'A'
+PASS select2.options[2].value is '1.5'
+PASS select2.options[2].textContent is 'A.5'
+PASS select2.options[3].value is '2'
+PASS select2.options[3].textContent is 'B'
+PASS select2.options[4].value is '3'
+PASS select2.options[4].textContent is 'C'
+
+2.6 Insert Option beyond the end of Options
+PASS select2.options.length is 6
+PASS select2.selectedIndex is 1
+PASS select2.options[0].value is '0'
+PASS select2.options[0].textContent is 'Z'
+PASS select2.options[1].value is '1'
+PASS select2.options[1].textContent is 'A'
+PASS select2.options[2].value is '1.5'
+PASS select2.options[2].textContent is 'A.5'
+PASS select2.options[3].value is '2'
+PASS select2.options[3].textContent is 'B'
+PASS select2.options[4].value is '3'
+PASS select2.options[4].textContent is 'C'
+PASS select2.options[5].value is '4'
+PASS select2.options[5].textContent is 'D'
+
+2.7 Add an Option at index -1
+PASS select2.options.length is 7
+PASS select2.selectedIndex is 1
+PASS select2.options[0].value is '0'
+PASS select2.options[0].textContent is 'Z'
+PASS select2.options[1].value is '1'
+PASS select2.options[1].textContent is 'A'
+PASS select2.options[2].value is '1.5'
+PASS select2.options[2].textContent is 'A.5'
+PASS select2.options[3].value is '2'
+PASS select2.options[3].textContent is 'B'
+PASS select2.options[4].value is '3'
+PASS select2.options[4].textContent is 'C'
+PASS select2.options[5].value is '4'
+PASS select2.options[5].textContent is 'D'
+PASS select2.options[6].value is '5'
+PASS select2.options[6].textContent is 'E'
+
+2.8 Add an Option at index -2
+PASS select2.options.add(option2, -2) threw exception Error: INDEX_SIZE_ERR: DOM Exception 1.
+PASS select2.options.length is 7
+PASS select2.selectedIndex is 1
+
+2.9 Add an Option at index -Infinity
+PASS select2.options.add(option2, -1/0) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS select2.options.length is 7
+PASS select2.selectedIndex is 1
+
+2.10 Add an Option at index NaN
+PASS select2.options.add(option2, 0/0) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS select2.options.length is 7
+PASS select2.selectedIndex is 1
+
+2.11 Add an Option at index Infinity
+PASS select2.options.add(option2, 1/0) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS select2.options.length is 7
+PASS select2.selectedIndex is 1
+
+2.12 Add a non-Option element
+PASS select2.options.add(option2, 1) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS select2.options.length is 7
+PASS select2.selectedIndex is 1
+
+2.13 Add a non-element (string)
+PASS select2.options.add(option2, 1) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS select2.options.length is 7
+PASS select2.selectedIndex is 1
+
+2.14 Add a non-element (number)
+PASS select2.options.add(option2, 1) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS select2.options.length is 7
+PASS select2.selectedIndex is 1
+
+2.15 Add undefined
+PASS select2.options.add(option2, 1) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS select2.options.length is 7
+PASS select2.selectedIndex is 1
+
+2.16 Add null
+PASS select2.options.add(option2, 1) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS select2.options.length is 7
+PASS select2.selectedIndex is 1
+
+2.17 Add negative infinity
+PASS select2.options.add(option2, 1) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS select2.options.length is 7
+PASS select2.selectedIndex is 1
+
+2.18 Add NaN
+PASS select2.options.add(option2, 1) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS select2.options.length is 7
+PASS select2.selectedIndex is 1
+
+2.19 Add positive infinity
+PASS select2.options.add(option2, 1) threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
+PASS select2.options.length is 7
+PASS select2.selectedIndex is 1
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="resources/js-test-style.css">
+<script src="resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<div>
+<select id="select1"></select>
+<select id="select2"></select>
+</div>
+<script src="resources/select-options-add.js"></script>
+<script src="resources/js-test-post.js"></script>
+</body>
+</html>
+2006-07-10 David Kilzer <ddkilzer@kilzer.net>
+
+ Reviewed by Darin.
+
+ - fix http://bugzilla.opendarwin.org/show_bug.cgi?id=9179
+ Implement select.options.add() method
+
+ Tests:
+ - fast/dom/select-selectedIndex-multiple.html
+ - fast/dom/select-selectedIndex.html
+ - fast/js/select-options-add.html
+
+ * DerivedSources.make: Added JSHTMLOptionsCollection.h.
+ * ForwardingHeaders/kjs/operations.h: Added.
+ * WebCore.xcodeproj/project.pbxproj: Added new source files.
+ * bindings/js/JSHTMLOptionsCollectionCustom.cpp: Added.
+ (WebCore::JSHTMLOptionsCollection::length):
+ (WebCore::JSHTMLOptionsCollection::setLength):
+ (WebCore::JSHTMLOptionsCollection::indexSetter):
+ * bindings/js/kjs_html.cpp: Removed JSHTMLOptionsCollection implementation.
+ Renamed classes and methods for consistency.
+ (KJS::JSHTMLElement::selectGetter):
+ (KJS::JSHTMLElement::put):
+ (KJS::JSHTMLElement::selectSetter):
+ (KJS::JSHTMLCollection::JSHTMLCollection):
+ (KJS::JSHTMLCollectionProtoFunc::callAsFunction):
+ (KJS::getHTMLOptionsCollection):
+ * bindings/js/kjs_html.h: Ditto.
+ * bindings/scripts/CodeGeneratorJS.pm: Added support for HasCustomIndexSetter class attribute.
+ Added support for Optional parameter attribute, which makes generated code assume overloaded
+ implementation methods are available for a JavaScript function with optional arguments. Changed
+ local 'impl' variables to 'imp' so that impl() methods could be called without class designation.
+ * html/HTMLOptionElement.idl: Added GenerateNativeConverter attribute.
+ * html/HTMLOptionsCollection.cpp: Added methods used by generated JSHTMLOptionsCollection class.
+ (WebCore::HTMLOptionsCollection::HTMLOptionsCollection):
+ (WebCore::HTMLOptionsCollection::add):
+ (WebCore::HTMLOptionsCollection::selectedIndex):
+ (WebCore::HTMLOptionsCollection::setSelectedIndex):
+ (WebCore::HTMLOptionsCollection::setLength):
+ * html/HTMLOptionsCollection.h: Ditto.
+ * html/HTMLOptionsCollection.idl: Added.
+
2006-07-10 David Harrison <harrison@apple.com>
Reviewed by Dave Hyatt.
JSHTMLLinkElement.h \
JSHTMLMenuElement.h \
JSHTMLOptionElement.h \
+ JSHTMLOptionsCollection.h \
JSHTMLOptGroupElement.h \
JSHTMLQuoteElement.h \
JSHTMLMapElement.h \
--- /dev/null
+#include <JavaScriptCore/operations.h>
1CD4418E0A4CE76F00A007AB /* northEastSouthWestResizeCursor.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 1CD4418A0A4CE76F00A007AB /* northEastSouthWestResizeCursor.tiff */; };
1CD4418F0A4CE76F00A007AB /* northSouthResizeCursor.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 1CD4418B0A4CE76F00A007AB /* northSouthResizeCursor.tiff */; };
1CD441900A4CE76F00A007AB /* northWestSouthEastResizeCursor.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 1CD4418C0A4CE76F00A007AB /* northWestSouthEastResizeCursor.tiff */; };
+ 448A29BF0A46D9CB0030759F /* JSHTMLOptionsCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 448A29BD0A46D9CB0030759F /* JSHTMLOptionsCollection.h */; };
+ 448A29C00A46D9CB0030759F /* JSHTMLOptionsCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 448A29BE0A46D9CB0030759F /* JSHTMLOptionsCollection.cpp */; };
+ 448AD27C0A48137A0023D179 /* JSHTMLOptionsCollectionCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 448AD27A0A4813790023D179 /* JSHTMLOptionsCollectionCustom.cpp */; };
4E1959210A39DABA00220FE5 /* MediaFeatureNames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E19591F0A39DABA00220FE5 /* MediaFeatureNames.cpp */; };
4E1959220A39DABA00220FE5 /* MediaFeatureNames.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E1959200A39DABA00220FE5 /* MediaFeatureNames.h */; };
4E1959290A39DACC00220FE5 /* MediaQuery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E1959230A39DACC00220FE5 /* MediaQuery.cpp */; };
1CD4418C0A4CE76F00A007AB /* northWestSouthEastResizeCursor.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = northWestSouthEastResizeCursor.tiff; sourceTree = "<group>"; };
2D90660B0665D937006B6F1A /* ClipboardMac.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = ClipboardMac.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
2D90660C0665D937006B6F1A /* ClipboardMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ClipboardMac.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
+ 448A29BD0A46D9CB0030759F /* JSHTMLOptionsCollection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSHTMLOptionsCollection.h; sourceTree = "<group>"; };
+ 448A29BE0A46D9CB0030759F /* JSHTMLOptionsCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLOptionsCollection.cpp; sourceTree = "<group>"; };
+ 448AD27A0A4813790023D179 /* JSHTMLOptionsCollectionCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLOptionsCollectionCustom.cpp; sourceTree = "<group>"; };
4758C44308C5F217009BAF05 /* KCanvasPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KCanvasPath.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
4E19591F0A39DABA00220FE5 /* MediaFeatureNames.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MediaFeatureNames.cpp; sourceTree = "<group>"; };
4E1959200A39DABA00220FE5 /* MediaFeatureNames.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MediaFeatureNames.h; sourceTree = "<group>"; };
A80E7E910A1A83E3007FB8C5 /* JSHTMLOptGroupElement.h */,
A80E7E900A1A83E3007FB8C5 /* JSHTMLOptionElement.cpp */,
A80E7E8F0A1A83E3007FB8C5 /* JSHTMLOptionElement.h */,
+ 448A29BE0A46D9CB0030759F /* JSHTMLOptionsCollection.cpp */,
+ 448A29BD0A46D9CB0030759F /* JSHTMLOptionsCollection.h */,
1AE2AB9E0A1CE90500B42B25 /* JSHTMLParagraphElement.cpp */,
1AE2AB9F0A1CE90500B42B25 /* JSHTMLParagraphElement.h */,
1AE2ABA00A1CE90500B42B25 /* JSHTMLParamElement.cpp */,
A80E7E630A1A82EC007FB8C5 /* JSHTMLInputElementBase.h */,
A826E8AD0A1A8F2300CD1BB6 /* JSHTMLOptionElementConstructor.cpp */,
A826E8AC0A1A8F2300CD1BB6 /* JSHTMLOptionElementConstructor.h */,
+ 448AD27A0A4813790023D179 /* JSHTMLOptionsCollectionCustom.cpp */,
93B70D4109EB0C7C009D8468 /* JSXMLHttpRequest.cpp */,
93B70D4209EB0C7C009D8468 /* JSXMLHttpRequest.h */,
93B70D4309EB0C7C009D8468 /* JSXMLSerializer.cpp */,
ABE7B5240A489F830031881C /* DeprecatedRenderSelect.h in Headers */,
DB23C2CC0A508D29002489EB /* IndentOutdentCommand.h in Headers */,
BCCD74DC0A4C8D35005FDA6D /* HTMLViewSourceDocument.h in Headers */,
+ 448A29BF0A46D9CB0030759F /* JSHTMLOptionsCollection.h in Headers */,
1A8086CC0A4D097600DFB6A7 /* DOMCSSInternal.h in Headers */,
1A1D13800A5325520064BF5F /* DOMXPath.h in Headers */,
1A1D13CA0A5329090064BF5F /* DOMXPathInternal.h in Headers */,
51F11E150A48C2920034A24E /* SQLTransaction.cpp in Sources */,
DB23C2CB0A508D29002489EB /* IndentOutdentCommand.cpp in Sources */,
BCCD74E50A4C8DDF005FDA6D /* HTMLViewSourceDocument.cpp in Sources */,
+ 448A29C00A46D9CB0030759F /* JSHTMLOptionsCollection.cpp in Sources */,
+ 448AD27C0A48137A0023D179 /* JSHTMLOptionsCollectionCustom.cpp in Sources */,
E1052C320A4D70010072D99B /* DOMEventsNonstandard.mm in Sources */,
516149ED0A525E3A003DFC7A /* SiteIcon.cpp in Sources */,
1A1D13810A5325520064BF5F /* DOMXPath.mm in Sources */,
--- /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.
+ */
+
+#include "config.h"
+#include "JSHTMLOptionsCollection.h"
+
+#include "ExceptionCode.h"
+#include "HTMLNames.h"
+#include "HTMLOptionElement.h"
+#include "HTMLOptionsCollection.h"
+#include "HTMLSelectElement.h"
+#include "JSHTMLOptionElement.h"
+
+#include <kjs/operations.h>
+
+using namespace KJS;
+
+namespace WebCore {
+
+JSValue* JSHTMLOptionsCollection::length(ExecState* exec) const
+{
+ HTMLOptionsCollection* imp = static_cast<HTMLOptionsCollection*>(impl());
+ return jsNumber(imp->length());
+}
+
+void JSHTMLOptionsCollection::setLength(ExecState* exec, JSValue* value)
+{
+ HTMLOptionsCollection* imp = static_cast<HTMLOptionsCollection*>(impl());
+ ExceptionCode ec = 0;
+ unsigned newLength = 0;
+ double lengthValue;
+ if (!value->isUndefinedOrNull() && value->getNumber(lengthValue)) {
+ if (isNaN(lengthValue) || isInf(lengthValue))
+ newLength = 0;
+ else if (lengthValue < 0.0)
+ ec = INDEX_SIZE_ERR;
+ else if (lengthValue > static_cast<double>(UINT_MAX))
+ newLength = UINT_MAX;
+ else
+ newLength = static_cast<unsigned>(lengthValue);
+ }
+ if (!ec)
+ imp->setLength(newLength, ec);
+ setDOMException(exec, ec);
+}
+
+void JSHTMLOptionsCollection::indexSetter(KJS::ExecState* exec, const KJS::Identifier &propertyName, KJS::JSValue* value, int attr)
+{
+ bool ok;
+ unsigned index = propertyName.toUInt32(&ok);
+ if (!ok)
+ return;
+
+ HTMLOptionsCollection* imp = static_cast<HTMLOptionsCollection*>(impl());
+ HTMLSelectElement* base = static_cast<HTMLSelectElement*>(imp->base());
+ if (value->isUndefinedOrNull())
+ base->remove(index);
+ else {
+ ExceptionCode ec = 0;
+ HTMLOptionElement* option = toHTMLOptionElement(value);
+ if (!option)
+ ec = TYPE_MISMATCH_ERR;
+ else
+ base->setOption(index, option, ec);
+ setDOMException(exec, ec);
+ }
+}
+
+}
#include "HTMLTableRowElement.h"
#include "HTMLTableSectionElement.h"
#include "JSHTMLImageElement.h"
+#include "JSHTMLOptionsCollection.h"
#include "NameNodeList.h"
#include "RenderLayer.h"
#include "Text.h"
case SelectValue: return jsString(select.value());
case SelectLength: return jsNumber(select.length());
case SelectForm: return toJS(exec, select.form()); // type HTMLFormElement
- case SelectOptions: return getSelectHTMLCollection(exec, select.options().get(), &select); // type JSHTMLCollection
+ case SelectOptions: return getHTMLOptionsCollection(exec, select.options().get());
case SelectDisabled: return jsBoolean(select.disabled());
case SelectMultiple: return jsBoolean(select.multiple());
case SelectName: return jsString(select.name());
bool ok;
/*unsigned u =*/ propertyName.toUInt32(&ok);
if (ok) {
- JSObject* coll = static_cast<JSObject*>(getSelectHTMLCollection(exec, select.options().get(), &select));
+ JSObject* coll = static_cast<JSObject*>(getHTMLOptionsCollection(exec, select.options().get()));
coll->put(exec,propertyName,value);
return;
}
case SelectSelectedIndex: { select.setSelectedIndex(value->toInt32(exec)); return; }
case SelectValue: { select.setValue(str); return; }
case SelectLength: { // read-only according to the NS spec, but webpages need it writeable
- JSObject* coll = static_cast<JSObject*>(getSelectHTMLCollection(exec, select.options().get(), &select));
+ JSObject* coll = static_cast<JSObject*>(getHTMLOptionsCollection(exec, select.options().get()));
coll->put(exec,lengthPropertyName,value);
return;
}
}
// -------------------------------------------------------------------------
-/* Source for HTMLCollectionProtoTable. Use "make hashtables" to regenerate.
-@begin HTMLCollectionProtoTable 3
+/* Source for JSHTMLCollectionProtoTable. Use "make hashtables" to regenerate.
+@begin JSHTMLCollectionProtoTable 3
item JSHTMLCollection::Item DontDelete|Function 1
namedItem JSHTMLCollection::NamedItem DontDelete|Function 1
tags JSHTMLCollection::Tags DontDelete|Function 1
@end
*/
-KJS_DEFINE_PROTOTYPE(HTMLCollectionProto)
-KJS_IMPLEMENT_PROTOFUNC(HTMLCollectionProtoFunc)
-KJS_IMPLEMENT_PROTOTYPE("HTMLCollection",HTMLCollectionProto,HTMLCollectionProtoFunc)
+KJS_IMPLEMENT_PROTOFUNC(JSHTMLCollectionProtoFunc)
+KJS_IMPLEMENT_PROTOTYPE("HTMLCollection",JSHTMLCollectionProto,JSHTMLCollectionProtoFunc)
const ClassInfo JSHTMLCollection::info = { "Collection", 0, 0, 0 };
-JSHTMLCollection::JSHTMLCollection(ExecState* exec, HTMLCollection *c)
+JSHTMLCollection::JSHTMLCollection(ExecState* exec, HTMLCollection* c)
: m_impl(c)
{
- setPrototype(HTMLCollectionProto::self(exec));
+ setPrototype(JSHTMLCollectionProto::self(exec));
}
JSHTMLCollection::~JSHTMLCollection()
return new DOMNamedNodesCollection(exec, namedItems);
}
-JSValue *HTMLCollectionProtoFunc::callAsFunction(ExecState* exec, JSObject* thisObj, const List &args)
+JSValue* JSHTMLCollectionProtoFunc::callAsFunction(ExecState* exec, JSObject* thisObj, const List &args)
{
if (!thisObj->inherits(&JSHTMLCollection::info))
return throwError(exec, TypeError);
}
}
-// -------------------------------------------------------------------------
-
-JSHTMLSelectCollection::JSHTMLSelectCollection(ExecState* exec, HTMLCollection *c, HTMLSelectElement* e)
- : JSHTMLCollection(exec, c), m_element(e)
-{
-}
-
-JSValue *JSHTMLSelectCollection::selectedIndexGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot)
-{
- JSHTMLSelectCollection *thisObj = static_cast<JSHTMLSelectCollection*>(slot.slotBase());
- return jsNumber(thisObj->m_element->selectedIndex());
-}
-
-bool JSHTMLSelectCollection::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
-{
- if (propertyName == "selectedIndex") {
- slot.setCustom(this, selectedIndexGetter);
- //result = jsNumber(m_element->selectedIndex());
- return true;
- }
-
- return JSHTMLCollection::getOwnPropertySlot(exec, propertyName, slot);
-}
-
-void JSHTMLSelectCollection::put(ExecState* exec, const Identifier &propertyName, JSValue *value, int)
-{
-#ifdef KJS_VERBOSE
- kdDebug(6070) << "JSHTMLSelectCollection::put " << propertyName.deprecatedString() << endl;
-#endif
- if ( propertyName == "selectedIndex" )
- m_element->setSelectedIndex(value->toInt32(exec));
- else if (propertyName == lengthPropertyName) {
- // resize ?
- if (value->isNumber()) {
- double newLen;
- if (value->getNumber(newLen)) {
- int exception = 0;
- if (newLen >= 0) {
- m_element->setLength(unsigned(floor(newLen)), exception);
- setDOMException(exec, exception);
- }
- }
- } else {
- int exception = 0;
- m_element->setLength(0, exception);
- setDOMException(exec, exception);
- }
- } else {
- // an index ?
- bool ok;
- unsigned i = propertyName.toUInt32(&ok);
- if (ok) {
- if (value->isUndefinedOrNull()) {
- // null and undefined delete. others, too ?
- m_element->remove(i);
- } else {
- WebCore::Node *option = toNode(value);
- // is v an option element ?
- if (!option || !option->hasTagName(optionTag))
- return;
-
- int exception = 0;
- m_element->setOption(i, static_cast<HTMLOptionElement*>(option), exception);
- setDOMException(exec, exception);
- }
- }
- }
-}
-
////////////////////// Image Object ////////////////////////
ImageConstructorImp::ImageConstructorImp(ExecState* exec, Document* d)
return cacheDOMObject<HTMLCollection, JSHTMLCollection>(exec, c);
}
-JSValue *getSelectHTMLCollection(ExecState* exec, HTMLCollection *c, HTMLSelectElement* e)
+JSValue* getHTMLOptionsCollection(ExecState* exec, HTMLOptionsCollection* c)
{
- DOMObject *ret;
+ DOMObject* ret;
if (!c)
return jsNull();
ScriptInterpreter* interp = static_cast<ScriptInterpreter*>(exec->dynamicInterpreter());
if ((ret = interp->getDOMObject(c)))
return ret;
else {
- ret = new JSHTMLSelectCollection(exec, c, e);
- interp->putDOMObject(c,ret);
+ ret = new JSHTMLOptionsCollection(exec, c);
+ interp->putDOMObject(c, ret);
return ret;
}
}
class HTMLCollection;
class HTMLDocument;
class HTMLElement;
+ class HTMLOptionsCollection;
class HTMLSelectElement;
class HTMLTableCaptionElement;
class HTMLTableSectionElement;
WebCore::HTMLTableCaptionElement* toHTMLTableCaptionElement(JSValue*); // returns 0 if passed-in value is not a JSHTMLElement object for a HTMLTableCaptionElement
WebCore::HTMLTableSectionElement* toHTMLTableSectionElement(JSValue*); // returns 0 if passed-in value is not a JSHTMLElement object for a HTMLTableSectionElement
+ KJS_DEFINE_PROTOTYPE(JSHTMLCollectionProto)
+
class JSHTMLCollection : public DOMObject {
public:
JSHTMLCollection(ExecState*, WebCore::HTMLCollection*);
static JSValue* nameGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
};
- class JSHTMLSelectCollection : public JSHTMLCollection {
- public:
- JSHTMLSelectCollection(ExecState*, WebCore::HTMLCollection*, WebCore::HTMLSelectElement*);
- virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
- virtual void put(ExecState*, const Identifier& propertyName, JSValue*, int attr = None);
- private:
- static JSValue* selectedIndexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
-
- RefPtr<WebCore::HTMLSelectElement> m_element;
- };
-
class HTMLAllCollection : public JSHTMLCollection {
public:
HTMLAllCollection(ExecState* exec, WebCore::HTMLCollection* c) :
};
JSValue* getHTMLCollection(ExecState*, WebCore::HTMLCollection*);
- JSValue* getSelectHTMLCollection(ExecState*, WebCore::HTMLCollection*, WebCore::HTMLSelectElement*);
+ JSValue* getHTMLOptionsCollection(ExecState*, WebCore::HTMLOptionsCollection*);
JSValue* getAllHTMLCollection(ExecState*, WebCore::HTMLCollection*);
} // namespace
}
}
}
-
+
+ # Index setter
+ if ($dataNode->extendedAttributes->{"HasCustomIndexSetter"}) {
+ push(@headerContent, " void indexSetter(KJS::ExecState*, const KJS::Identifier &propertyName, KJS::JSValue*, int attr);\n");
+ }
+
if (!$hasParent) {
push(@headerContent, " $implClassName* impl() const { return m_impl.get(); }\n");
push(@headerContent, "private:\n");
push(@implContent, "}\n\n");
push(@implContent, "JSValue* ${className}::getValueProperty(ExecState* exec, int token) const\n{\n");
- push(@implContent, " $implClassName* impl = static_cast<$implClassName*>(${className}::impl());\n\n");
+ push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(impl());\n\n");
push(@implContent, " switch (token) {\n");
foreach my $attribute (@{$dataNode->attributes}) {
push(@implContent, " return JS" . $constructorType . "::getConstructor(exec);\n");
} elsif (!@{$attribute->getterExceptions}) {
push(@implContent, " case " . ucfirst($name) . "AttrNum:\n");
- push(@implContent, " return " . NativeToJSValue($attribute->signature, "impl->$name()") . ";\n");
+ push(@implContent, " return " . NativeToJSValue($attribute->signature, "imp->$name()") . ";\n");
} else {
push(@implContent, " case " . ucfirst($name) . "AttrNum: {\n");
push(@implContent, " ExceptionCode ec = 0;\n");
- push(@implContent, " KJS::JSValue* result = " . NativeToJSValue($attribute->signature, "impl->$name(ec)") . ";\n");
+ push(@implContent, " KJS::JSValue* result = " . NativeToJSValue($attribute->signature, "imp->$name(ec)") . ";\n");
push(@implContent, " setDOMException(exec, ec);\n");
push(@implContent, " return result;\n");
push(@implContent, " }\n");
}
if ($hasReadWriteProperties) {
push(@implContent, "void ${className}::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr)\n");
- push(@implContent, "{\n lookupPut<$className, $parentClassName>" .
- "(exec, propertyName, value, attr, &${className}Table, this);\n}\n\n");
-
+ if ($dataNode->extendedAttributes->{"HasCustomIndexSetter"}) {
+ push(@implContent, "{\n" .
+ " if (!lookupPut<$className>(exec, propertyName, value, attr, &${className}Table, this))\n");
+ push(@implContent, " indexSetter(exec, propertyName, value, attr);\n");
+ push(@implContent, "}\n\n");
+ }
+ else {
+ push(@implContent, "{\n lookupPut<$className, $parentClassName>" .
+ "(exec, propertyName, value, attr, &${className}Table, this);\n}\n\n");
+ }
+
push(@implContent, "void ${className}::putValueProperty(ExecState* exec, int token, JSValue* value, int /*attr*/)\n");
push(@implContent, "{\n");
- push(@implContent, " $implClassName* impl = static_cast<$implClassName*>(${className}::impl());\n\n");
+ push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(impl());\n\n");
push(@implContent, " switch (token) {\n");
foreach my $attribute (@{$dataNode->attributes}) {
} 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, " imp->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};
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, " (void)imp;\n");
}
push(@implContent, "}\n\n"); # end function
}
push(@implContent, " if (!thisObj->inherits(&${className}::info))\n");
push(@implContent, " return throwError(exec, TypeError);\n\n");
- push(@implContent, " $implClassName* impl = static_cast<$implClassName*>(static_cast<$className*>(thisObj)->impl());\n\n");
-
-
+ push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(thisObj)->impl());\n\n");
+
push(@implContent, " switch (id) {\n");
- foreach my $function (@{$dataNode->functions}) {
+ foreach my $function (@{$dataNode->functions}) {
push(@implContent, " case ${className}::" . ucfirst($function->signature->name) . "FuncNum: {\n");
-
+
if ($function->signature->extendedAttributes->{"Custom"}) {
push(@implContent, " return static_cast<${className}*>(thisObj)->" . $function->signature->name . "(exec, args);\n }\n");
next;
}
-
+
AddIncludesForType($function->signature->type);
-
+
+ if (@{$function->raisesExceptions}) {
+ push(@implContent, " ExceptionCode ec = 0;\n");
+ }
+
my $paramIndex = 0;
- my $functionString = "impl->" . $function->signature->name . "(";
+ my $functionString = "imp->" . $function->signature->name . "(";
my $numParameters = @{$function->parameters};
-
+ my $hasOptionalArguments = 0;
+
foreach my $parameter (@{$function->parameters}) {
+ if (!$hasOptionalArguments && $parameter->extendedAttributes->{"Optional"}) {
+ push(@implContent, "\n int argsCount = args.size();\n");
+ $hasOptionalArguments = 1;
+ }
+
+ if ($hasOptionalArguments) {
+ push(@implContent, " if (argsCount < " . ($paramIndex + 1) . ") {\n");
+ GenerateImplementationFunctionCall($function, $functionString, $paramIndex, " " x 3);
+ push(@implContent, " }\n\n");
+ }
+
my $name = $parameter->name;
push(@implContent, " bool ${name}Ok;\n") if TypeCanFailConversion($parameter);
push(@implContent, " " . GetNativeType($parameter) . " $name = " . JSValueToNative($parameter, "args[$paramIndex]", TypeCanFailConversion($parameter) ? "${name}Ok" : undef) . ";\n");
- if (TypeCanFailConversion($parameter)) {
- push(@implContent, " if (!${name}Ok) {\n");
- push(@implContent, " setDOMException(exec, TYPE_MISMATCH_ERR);\n");
- push(@implContent, " return jsUndefined();\n }\n");
- }
-
+ if (TypeCanFailConversion($parameter)) {
+ push(@implContent, " if (!${name}Ok) {\n");
+ push(@implContent, " setDOMException(exec, TYPE_MISMATCH_ERR);\n");
+ push(@implContent, " return jsUndefined();\n }\n");
+ }
+
# If a parameter is "an index", it should throw an INDEX_SIZE_ERR
# exception
if ($parameter->extendedAttributes->{"IsIndex"}) {
push(@implContent, " setDOMException(exec, INDEX_SIZE_ERR);\n");
push(@implContent, " return jsUndefined();\n }\n");
}
-
+
$functionString .= ", " if $paramIndex;
$functionString .= $name;
$paramIndex++;
}
-
- if (@{$function->raisesExceptions}) {
- $functionString .= ", " if $paramIndex;
- $functionString .= "ec";
- push(@implContent, " ExceptionCode ec = 0;\n");
- }
- $functionString .= ")";
-
- if ($function->signature->type eq "void") {
- push(@implContent, "\n $functionString;\n");
- push(@implContent, " setDOMException(exec, ec);\n") if @{$function->raisesExceptions};
- push(@implContent, " return jsUndefined();\n");
- } else {
- push(@implContent, "\n KJS::JSValue* result = " . NativeToJSValue($function->signature, $functionString) . ";\n");
- push(@implContent, " setDOMException(exec, ec);\n") if @{$function->raisesExceptions};
- push(@implContent, " return result;\n");
- }
- push(@implContent, " }\n");
+ push(@implContent, "\n");
+ GenerateImplementationFunctionCall($function, $functionString, $paramIndex, " " x 2);
+
+ push(@implContent, " }\n"); # end case
}
- push(@implContent, " }\n");
+ push(@implContent, " }\n"); # end switch
push(@implContent, " return 0;\n");
- push(@implContent, "}\n")
+ push(@implContent, "}\n");
}
-
+
if ($dataNode->extendedAttributes->{"HasIndexGetter"}) {
push(@implContent, "\nJSValue* ${className}::indexGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot)\n");
push(@implContent, "{\n");
push(@implContent, " return toJS(exec, static_cast<$implClassName*>(thisObj->impl())->item(slot.index()));\n");
push(@implContent, "}\n");
}
-
+
if (!$hasParent) {
my $implContent = << "EOF";
KJS::JSValue* toJS(KJS::ExecState* exec, $implClassName* obj)
push(@implContent, "\n#endif // ${conditional}_SUPPORT\n") if $conditional;
}
+sub GenerateImplementationFunctionCall()
+{
+ my $function = shift;
+ my $functionString = shift;
+ my $paramIndex = shift;
+ my $indent = shift;
+
+ if (@{$function->raisesExceptions}) {
+ $functionString .= ", " if $paramIndex;
+ $functionString .= "ec";
+ }
+ $functionString .= ")";
+
+ if ($function->signature->type eq "void") {
+ push(@implContent, $indent . "$functionString;\n");
+ push(@implContent, $indent . "setDOMException(exec, ec);\n") if @{$function->raisesExceptions};
+ push(@implContent, $indent . "return jsUndefined();\n");
+ } else {
+ push(@implContent, "\n" . $indent . "KJS::JSValue* result = " . NativeToJSValue($function->signature, $functionString) . ";\n");
+ push(@implContent, $indent . "setDOMException(exec, ec);\n") if @{$function->raisesExceptions};
+ push(@implContent, $indent . "return result;\n");
+ }
+}
+
sub GetNativeType
{
my $signature = shift;
if ($type eq "boolean") {
return 0;
} elsif ($type eq "unsigned long" or $type eq "long") {
- return 0; # or can it?
+ $implIncludes{"ExceptionCode.h"} = 1;
+ return 1;
} elsif ($type eq "unsigned short") {
return 0; # or can it?
} elsif ($type eq "CompareHow") {
$type eq "XPathResult" or
$type eq "SVGMatrix" or
$type eq "SVGRect" or
- $type eq "SVGElement") {
+ $type eq "SVGElement" or
+ $type eq "HTMLOptionElement") {
return 0;
} else {
die "Don't know whether a JS value can fail conversion to type $type."
} elsif ($type eq "unsigned long" or
$type eq "long" or
$type eq "unsigned short") {
- return "$value->toInt32(exec)";
+ if ($maybeOkParam) {
+ return "$value->toInt32(exec${maybeOkParam})";
+ } else {
+ return "$value->toInt32(exec)";
+ }
} elsif ($type eq "CompareHow") {
return "static_cast<Range::CompareHow>($value->toInt32(exec))";
} elsif ($type eq "float") {
} elsif ($type eq "StyleSheetList") {
$implIncludes{"StyleSheetList.h"} = 1;
$implIncludes{"kjs_css.h"} = 1;
- return "toJS(exec, $value, impl)";
+ return "toJS(exec, $value, imp)";
} elsif ($type eq "CSSStyleDeclaration" or $type eq "Rect") {
$implIncludes{"CSSStyleDeclaration.h"} = 1;
$implIncludes{"RectImpl.h"} = 1;
module html {
- interface [LegacyParent=KJS::JSHTMLElement] HTMLOptionElement : HTMLElement {
+ interface [LegacyParent=KJS::JSHTMLElement, GenerateNativeConverter] HTMLOptionElement : HTMLElement {
readonly attribute HTMLFormElement form;
attribute boolean defaultSelected;
attribute DOMString text
#include "HTMLOptionsCollection.h"
#include "ExceptionCode.h"
+#include "HTMLOptionElement.h"
#include "HTMLSelectElement.h"
namespace WebCore {
: HTMLCollection(select, SelectOptions)
{
ASSERT(!info);
-
info = select->collectionInfo();
}
-void HTMLOptionsCollection::setLength(unsigned, ExceptionCode& ec)
+void HTMLOptionsCollection::add(PassRefPtr<HTMLOptionElement> element, ExceptionCode &ec)
+{
+ add(element, length(), ec);
+}
+
+void HTMLOptionsCollection::add(PassRefPtr<HTMLOptionElement> element, int index, ExceptionCode &ec)
+{
+ HTMLOptionElement* newOption = element.get();
+
+ if (!newOption) {
+ ec = TYPE_MISMATCH_ERR;
+ return;
+ }
+
+ if (index < -1) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ ec = 0;
+ HTMLSelectElement* select = static_cast<HTMLSelectElement*>(m_base.get());
+
+ if (index == -1 || unsigned(index) >= length())
+ select->add(newOption, 0, ec);
+ else
+ select->add(newOption, static_cast<HTMLOptionElement*>(item(index)), ec);
+
+ ASSERT(ec == 0);
+}
+
+int HTMLOptionsCollection::selectedIndex() const
+{
+ return static_cast<HTMLSelectElement*>(m_base.get())->selectedIndex();
+}
+
+void HTMLOptionsCollection::setSelectedIndex(int index)
+{
+ static_cast<HTMLSelectElement*>(m_base.get())->setSelectedIndex(index);
+}
+
+void HTMLOptionsCollection::setLength(unsigned length, ExceptionCode& ec)
{
- ec = NOT_SUPPORTED_ERR;
+ static_cast<HTMLSelectElement*>(m_base.get())->setLength(length, ec);
}
} //namespace
#define HTML_HTMLOptionsCollectionImpl_H
#include "HTMLCollection.h"
+#include "HTMLOptionElement.h"
namespace WebCore {
public:
HTMLOptionsCollection(HTMLSelectElement*);
+ void add(PassRefPtr<HTMLOptionElement>, ExceptionCode&);
+ void add(PassRefPtr<HTMLOptionElement>, int index, ExceptionCode&);
+
+ int selectedIndex() const;
+ void setSelectedIndex(int);
+
void setLength(unsigned, ExceptionCode&);
};
--- /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 html {
+
+ interface [LegacyParent=KJS::JSHTMLCollection, HasCustomIndexSetter] HTMLOptionsCollection : HTMLCollection {
+ attribute long selectedIndex;
+ attribute [Custom] long length
+ setter raises (DOMException);
+
+ void add(in HTMLOptionElement option, in [Optional] unsigned long index)
+ raises (DOMException);
+ };
+}