From 1f367b6ab77afcd3d4dd219c29c53bce63bb9493 Mon Sep 17 00:00:00 2001 From: Dylan Piercey Date: Wed, 3 Jul 2019 11:48:51 -0700 Subject: [PATCH] Add optgroup support for controlled select elements --- .../vdom/morphdom/specialElHandlers.js | 32 +++++++++++++------ .../select-element-optgroup/expected.html | 30 +++++++++++++++++ .../select-element-optgroup/from.html | 14 ++++++++ .../fixtures/select-element-optgroup/index.js | 5 +++ .../fixtures/select-element-optgroup/to.html | 14 ++++++++ 5 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 test/morphdom/fixtures/select-element-optgroup/expected.html create mode 100644 test/morphdom/fixtures/select-element-optgroup/from.html create mode 100644 test/morphdom/fixtures/select-element-optgroup/index.js create mode 100644 test/morphdom/fixtures/select-element-optgroup/to.html diff --git a/src/runtime/vdom/morphdom/specialElHandlers.js b/src/runtime/vdom/morphdom/specialElHandlers.js index a9a240bce..a547aa038 100644 --- a/src/runtime/vdom/morphdom/specialElHandlers.js +++ b/src/runtime/vdom/morphdom/specialElHandlers.js @@ -9,6 +9,22 @@ function syncBooleanAttrProp(fromEl, toEl, name) { } } +function forEachOption(el, fn, i) { + var curChild = el.___firstChild; + + while (curChild) { + if (curChild.___nodeName === "option") { + fn(curChild, ++i); + } else { + i = forEachOption(curChild, fn, i); + } + + curChild = curChild.___nextSibling; + } + + return i; +} + // We use a JavaScript class to benefit from fast property lookup function SpecialElHandlers() {} SpecialElHandlers.prototype = { @@ -65,18 +81,16 @@ SpecialElHandlers.prototype = { }, select: function(fromEl, toEl) { if (!toEl.___hasAttribute("multiple")) { - var i = -1; var selected = 0; - var curChild = toEl.___firstChild; - while (curChild) { - if (curChild.___nodeName === "option") { - i++; - if (curChild.___hasAttribute("selected")) { + forEachOption( + toEl, + function(option, i) { + if (option.___hasAttribute("selected")) { selected = i; } - } - curChild = curChild.___nextSibling; - } + }, + -1 + ); if (fromEl.selectedIndex !== selected) { fromEl.selectedIndex = selected; diff --git a/test/morphdom/fixtures/select-element-optgroup/expected.html b/test/morphdom/fixtures/select-element-optgroup/expected.html new file mode 100644 index 000000000..b0c6df289 --- /dev/null +++ b/test/morphdom/fixtures/select-element-optgroup/expected.html @@ -0,0 +1,30 @@ + +
+ "\n " + + + + + + + + + + + + +
\ No newline at end of file diff --git a/test/morphdom/fixtures/select-element-optgroup/index.js b/test/morphdom/fixtures/select-element-optgroup/index.js new file mode 100644 index 000000000..e0d041a13 --- /dev/null +++ b/test/morphdom/fixtures/select-element-optgroup/index.js @@ -0,0 +1,5 @@ +exports.verify = function(context, expect) { + var rootNode = context.rootNode; + var selectNode = rootNode.querySelector("select"); + expect(selectNode.selectedIndex).to.equal(1); +}; diff --git a/test/morphdom/fixtures/select-element-optgroup/to.html b/test/morphdom/fixtures/select-element-optgroup/to.html new file mode 100644 index 000000000..0529ccdcc --- /dev/null +++ b/test/morphdom/fixtures/select-element-optgroup/to.html @@ -0,0 +1,14 @@ +
+ +
\ No newline at end of file