summaryrefslogtreecommitdiff
path: root/node_modules/morphdom/src/specialElHandlers.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/morphdom/src/specialElHandlers.js')
-rw-r--r--node_modules/morphdom/src/specialElHandlers.js115
1 files changed, 115 insertions, 0 deletions
diff --git a/node_modules/morphdom/src/specialElHandlers.js b/node_modules/morphdom/src/specialElHandlers.js
new file mode 100644
index 0000000..ce213aa
--- /dev/null
+++ b/node_modules/morphdom/src/specialElHandlers.js
@@ -0,0 +1,115 @@
+function syncBooleanAttrProp(fromEl, toEl, name) {
+ if (fromEl[name] !== toEl[name]) {
+ fromEl[name] = toEl[name];
+ if (fromEl[name]) {
+ fromEl.setAttribute(name, '');
+ } else {
+ fromEl.removeAttribute(name);
+ }
+ }
+}
+
+export default {
+ OPTION: function(fromEl, toEl) {
+ var parentNode = fromEl.parentNode;
+ if (parentNode) {
+ var parentName = parentNode.nodeName.toUpperCase();
+ if (parentName === 'OPTGROUP') {
+ parentNode = parentNode.parentNode;
+ parentName = parentNode && parentNode.nodeName.toUpperCase();
+ }
+ if (parentName === 'SELECT' && !parentNode.hasAttribute('multiple')) {
+ if (fromEl.hasAttribute('selected') && !toEl.selected) {
+ // Workaround for MS Edge bug where the 'selected' attribute can only be
+ // removed if set to a non-empty value:
+ // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12087679/
+ fromEl.setAttribute('selected', 'selected');
+ fromEl.removeAttribute('selected');
+ }
+ // We have to reset select element's selectedIndex to -1, otherwise setting
+ // fromEl.selected using the syncBooleanAttrProp below has no effect.
+ // The correct selectedIndex will be set in the SELECT special handler below.
+ parentNode.selectedIndex = -1;
+ }
+ }
+ syncBooleanAttrProp(fromEl, toEl, 'selected');
+ },
+ /**
+ * The "value" attribute is special for the <input> element since it sets
+ * the initial value. Changing the "value" attribute without changing the
+ * "value" property will have no effect since it is only used to the set the
+ * initial value. Similar for the "checked" attribute, and "disabled".
+ */
+ INPUT: function(fromEl, toEl) {
+ syncBooleanAttrProp(fromEl, toEl, 'checked');
+ syncBooleanAttrProp(fromEl, toEl, 'disabled');
+
+ if (fromEl.value !== toEl.value) {
+ fromEl.value = toEl.value;
+ }
+
+ if (!toEl.hasAttribute('value')) {
+ fromEl.removeAttribute('value');
+ }
+ },
+
+ TEXTAREA: function(fromEl, toEl) {
+ var newValue = toEl.value;
+ if (fromEl.value !== newValue) {
+ fromEl.value = newValue;
+ }
+
+ var firstChild = fromEl.firstChild;
+ if (firstChild) {
+ // Needed for IE. Apparently IE sets the placeholder as the
+ // node value and vise versa. This ignores an empty update.
+ var oldValue = firstChild.nodeValue;
+
+ if (oldValue == newValue || (!newValue && oldValue == fromEl.placeholder)) {
+ return;
+ }
+
+ firstChild.nodeValue = newValue;
+ }
+ },
+ SELECT: function(fromEl, toEl) {
+ if (!toEl.hasAttribute('multiple')) {
+ var selectedIndex = -1;
+ var i = 0;
+ // We have to loop through children of fromEl, not toEl since nodes can be moved
+ // from toEl to fromEl directly when morphing.
+ // At the time this special handler is invoked, all children have already been morphed
+ // and appended to / removed from fromEl, so using fromEl here is safe and correct.
+ var curChild = fromEl.firstChild;
+ var optgroup;
+ var nodeName;
+ while(curChild) {
+ nodeName = curChild.nodeName && curChild.nodeName.toUpperCase();
+ if (nodeName === 'OPTGROUP') {
+ optgroup = curChild;
+ curChild = optgroup.firstChild;
+ // handle empty optgroups
+ if (!curChild) {
+ curChild = optgroup.nextSibling;
+ optgroup = null;
+ }
+ } else {
+ if (nodeName === 'OPTION') {
+ if (curChild.hasAttribute('selected')) {
+ selectedIndex = i;
+ break;
+ }
+ i++;
+ }
+ curChild = curChild.nextSibling;
+ if (!curChild && optgroup) {
+ curChild = optgroup.nextSibling;
+ optgroup = null;
+ }
+ }
+ }
+
+ fromEl.selectedIndex = selectedIndex;
+ }
+ }
+};