Commit b6ebe1b7 authored by keishi@chromium.org's avatar keishi@chromium.org

select.add() should support optgroup adding and before index

According to the spec (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#the-select-element) the idl for select.add is
void add((HTMLOptionElement or HTMLOptGroupElement) element, optional (HTMLElement or long)? before = null);

select.add should accept an optgroup as the first argument.
select.add should support an index as the second argument.

BUG=345345

Review URL: https://codereview.chromium.org/213773003

git-svn-id: svn://svn.chromium.org/blink/trunk@170259 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 08eeb990
......@@ -12,11 +12,11 @@ PASS aNode.isSameNode(void 0) is false
PASS aNode.lookupPrefix(aDOMImplementation) is null
PASS aNode.lookupPrefix(void 0) is null
PASS aNode.cloneNode(aDOMImplementation) instanceof HTMLDivElement is true
PASS aSelect.add(aDOMImplementation, aDOMImplementation) is undefined.
PASS aSelect.add(aDOMImplementation, anOption) is undefined.
PASS aSelect.add(aDOMImplementation, aDOMImplementation) threw exception TypeError: Failed to execute 'add' on 'HTMLSelectElement': No function was found that matched the signature provided..
PASS aSelect.add(aDOMImplementation, anOption) threw exception TypeError: Failed to execute 'add' on 'HTMLSelectElement': No function was found that matched the signature provided..
PASS aSelect.add(void 0, void 0) threw exception TypeError: Failed to execute 'add' on 'HTMLSelectElement': No function was found that matched the signature provided..
PASS aSelect.add(void 0, anOption) threw exception TypeError: Failed to execute 'add' on 'HTMLSelectElement': No function was found that matched the signature provided..
PASS aSelect.add(anOption, aDOMImplementation) is undefined.
PASS aSelect.add(void 0, void 0) is undefined.
PASS aSelect.add(void 0, anOption) is undefined.
PASS aSelect.add(anOption, void 0) is undefined.
PASS successfullyParsed is true
......
......@@ -40,11 +40,11 @@ shouldBeFalse("aNode.isSameNode(void 0)");
shouldBe("aNode.lookupPrefix(aDOMImplementation)", "null");
shouldBe("aNode.lookupPrefix(void 0)", "null");
shouldBeTrue("aNode.cloneNode(aDOMImplementation) instanceof HTMLDivElement");
shouldBeUndefined("aSelect.add(aDOMImplementation, aDOMImplementation)");
shouldBeUndefined("aSelect.add(aDOMImplementation, anOption)");
shouldThrow("aSelect.add(aDOMImplementation, aDOMImplementation)");
shouldThrow("aSelect.add(aDOMImplementation, anOption)");
shouldThrow("aSelect.add(void 0, void 0)");
shouldThrow("aSelect.add(void 0, anOption)");
shouldBeUndefined("aSelect.add(anOption, aDOMImplementation)");
shouldBeUndefined("aSelect.add(void 0, void 0)");
shouldBeUndefined("aSelect.add(void 0, anOption)");
shouldBeUndefined("aSelect.add(anOption, void 0)");
</script>
</body>
......
Test select.add() method
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
Test select
PASS addOption(0) is "X,0,1,2"
PASS addOption(1) is "0,X,1,2"
PASS addOption(2) is "0,1,X,2"
PASS addOption(3) is "0,1,2,X"
PASS addOption(100) is "0,1,2,X"
PASS addOption(-100) is "0,1,2,X"
PASS getSelectOptions() is "0,1,2,X"
PASS addOption(null) is "0,1,2,X"
PASS addOption(NaN) is "X,0,1,2"
PASS addOption(Infinity) is "X,0,1,2"
PASS addOption(-Infinity) is "X,0,1,2"
PASS addOption("foo") is "X,0,1,2"
PASS select.add() threw exception TypeError: Failed to execute 'add' on 'HTMLSelectElement': 1 argument required, but only 0 present..
PASS select.add("foo") threw exception TypeError: Failed to execute 'add' on 'HTMLSelectElement': No function was found that matched the signature provided..
PASS select.add("foo", 0) threw exception TypeError: Failed to execute 'add' on 'HTMLSelectElement': No function was found that matched the signature provided..
PASS select.add(null) threw exception TypeError: Failed to execute 'add' on 'HTMLSelectElement': No function was found that matched the signature provided..
PASS select.add(null, 0) threw exception TypeError: Failed to execute 'add' on 'HTMLSelectElement': No function was found that matched the signature provided..
PASS getSelectOptions() is "0,X,Y,1,2"
Test select multiple
PASS addOption(0) is "X,0,1,2"
PASS addOption(1) is "0,X,1,2"
PASS addOption(2) is "0,1,X,2"
PASS addOption(3) is "0,1,2,X"
PASS addOption(100) is "0,1,2,X"
PASS addOption(-100) is "0,1,2,X"
PASS getSelectOptions() is "0,1,2,X"
PASS addOption(null) is "0,1,2,X"
PASS addOption(NaN) is "X,0,1,2"
PASS addOption(Infinity) is "X,0,1,2"
PASS addOption(-Infinity) is "X,0,1,2"
PASS addOption("foo") is "X,0,1,2"
PASS select.add() threw exception TypeError: Failed to execute 'add' on 'HTMLSelectElement': 1 argument required, but only 0 present..
PASS select.add("foo") threw exception TypeError: Failed to execute 'add' on 'HTMLSelectElement': No function was found that matched the signature provided..
PASS select.add("foo", 0) threw exception TypeError: Failed to execute 'add' on 'HTMLSelectElement': No function was found that matched the signature provided..
PASS select.add(null) threw exception TypeError: Failed to execute 'add' on 'HTMLSelectElement': No function was found that matched the signature provided..
PASS select.add(null, 0) threw exception TypeError: Failed to execute 'add' on 'HTMLSelectElement': No function was found that matched the signature provided..
PASS getSelectOptions() is "0,X,Y,1,2"
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE html>
<html>
<head>
<script src="../../../resources/js-test.js"></script>
</head>
<body>
<script>
description('Test select.add() method');
debug('Test select');
test(false);
debug('Test select multiple');
test(true);
var select;
function resetSelect(multiple) {
select = document.createElement('select');
select.multiple = multiple;
select.appendChild(new Option("0", "0", false, false));
select.appendChild(new Option("1", "1", false, false));
select.appendChild(new Option("2", "2", false, false));
}
function addOption(index) {
select.add(new Option('X', 'X', false, false), index);
return getSelectOptions();
}
function getSelectOptions() {
var values = [];
for (var i = 0; i < select.options.length; ++i) {
values.push(select.options[i].value);
}
return values.join(",");
}
function test(multiple) {
resetSelect(multiple);
shouldBeEqualToString('addOption(0)', 'X,0,1,2');
resetSelect(multiple);
shouldBeEqualToString('addOption(1)', '0,X,1,2');
resetSelect(multiple);
shouldBeEqualToString('addOption(2)', '0,1,X,2');
resetSelect(multiple);
shouldBeEqualToString('addOption(3)', '0,1,2,X');
resetSelect(multiple);
shouldBeEqualToString('addOption(100)', '0,1,2,X');
resetSelect(multiple);
shouldBeEqualToString('addOption(-100)', '0,1,2,X');
resetSelect(multiple);
select.add(new Option('X', 'X', false, false));
shouldBeEqualToString('getSelectOptions()', '0,1,2,X');
resetSelect(multiple);
shouldBeEqualToString('addOption(null)', '0,1,2,X');
resetSelect(multiple);
shouldBeEqualToString('addOption(NaN)', 'X,0,1,2');
resetSelect(multiple);
shouldBeEqualToString('addOption(Infinity)', 'X,0,1,2');
resetSelect(multiple);
shouldBeEqualToString('addOption(-Infinity)', 'X,0,1,2');
resetSelect(multiple);
shouldBeEqualToString('addOption("foo")', 'X,0,1,2');
resetSelect(multiple);
shouldThrow('select.add()');
shouldThrow('select.add("foo")');
shouldThrow('select.add("foo", 0)');
shouldThrow('select.add(null)');
shouldThrow('select.add(null, 0)');
resetSelect(multiple);
var group = document.createElement('optgroup');
group.appendChild(new Option('X', 'X', false, false));
group.appendChild(new Option('Y', 'Y', false, false));
select.add(group, 1);
shouldBeEqualToString('getSelectOptions()', '0,X,Y,1,2');
}
</script>
</body>
</html>
......@@ -93,7 +93,7 @@ void HTMLOptionsCollection::add(PassRefPtr<HTMLOptionElement> element, int index
if (index == -1 || unsigned(index) >= length())
select.add(newOption, 0, exceptionState);
else
select.add(newOption, toHTMLOptionElement(item(index)), exceptionState);
select.addBeforeOptionAtIndex(newOption, index, exceptionState);
ASSERT(!exceptionState.hadException());
}
......
......@@ -204,13 +204,19 @@ void HTMLSelectElement::add(HTMLElement* element, HTMLElement* before, Exception
// Make sure the element is ref'd and deref'd so we don't leak it.
RefPtr<HTMLElement> protectNewChild(element);
if (!element || !(isHTMLOptionElement(element) || isHTMLHRElement(element)))
if (!element || !(isHTMLOptionElement(element) || isHTMLOptGroupElement(element) || isHTMLHRElement(element)))
return;
insertBefore(element, before, exceptionState);
setNeedsValidityCheck();
}
void HTMLSelectElement::addBeforeOptionAtIndex(HTMLElement* element, int beforeIndex, ExceptionState& exceptionState)
{
HTMLElement* beforeElement = toHTMLElement(options()->item(beforeIndex));
add(element, beforeElement, exceptionState);
}
void HTMLSelectElement::remove(int optionIndex)
{
int listIndex = optionToListIndex(optionIndex);
......
......@@ -63,6 +63,7 @@ public:
bool usesMenuList() const;
void add(HTMLElement*, HTMLElement* beforeElement, ExceptionState&);
void addBeforeOptionAtIndex(HTMLElement*, int beforeIndex, ExceptionState&);
using Node::remove;
void remove(int index);
......
......@@ -36,8 +36,9 @@ interface HTMLSelectElement : HTMLElement {
getter Element item(unsigned long index);
[RaisesException, StrictTypeChecking] setter HTMLOptionElement (unsigned long index, HTMLOptionElement? value);
Element namedItem([Default=Undefined] optional DOMString name);
[RaisesException] void add([Default=Undefined] optional HTMLElement element,
[Default=Undefined] optional HTMLElement before);
[RaisesException] void add(HTMLElement element,
[Default=Undefined] optional HTMLElement? before);
[RaisesException, ImplementedAs=addBeforeOptionAtIndex] void add(HTMLElement element, long before);
void remove(long index);
[RaisesException] void remove();
readonly attribute HTMLCollection selectedOptions;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment