Skip to content

Investigate possible cause of Long String in Array Access #109

@mkshiblu

Description

@mkshiblu
['$element', '$scope', function ($element, $scope) { var self = this, optionsMap = new NgMap(); self.selectValueMap = {}; self.ngModelCtrl = noopNgModelController; self.multiple = false; self.unknownOption = jqLite(window.document.createElement('option')); self.hasEmptyOption = false; self.emptyOption = undefined; self.renderUnknownOption = function (val) { var unknownVal = self.generateUnknownOptionValue(val); self.unknownOption.val(unknownVal); $element.prepend(self.unknownOption); setOptionAsSelected(self.unknownOption); $element.val(unknownVal); }; self.updateUnknownOption = function (val) { var unknownVal = self.generateUnknownOptionValue(val); self.unknownOption.val(unknownVal); setOptionAsSelected(self.unknownOption); $element.val(unknownVal); }; self.generateUnknownOptionValue = function (val) { return '? ' + hashKey(val) + ' ?'; }; self.removeUnknownOption = function () { if (self.unknownOption.parent()) self.unknownOption.remove(); }; self.selectEmptyOption = function () { if (self.emptyOption) { $element.val(''); setOptionAsSelected(self.emptyOption); } }; self.unselectEmptyOption = function () { if (self.hasEmptyOption) { self.emptyOption.removeAttr('selected'); } }; $scope.$on('$destroy', function () { self.renderUnknownOption = noop; }); self.readValue = function readSingleValue() { var val = $element.val(); var realVal = val in self.selectValueMap ? self.selectValueMap[val] : val; if (self.hasOption(realVal)) { return realVal; } return null; }; self.writeValue = function writeSingleValue(value) { var currentlySelectedOption = $element[0].options[$element[0].selectedIndex]; if (currentlySelectedOption) currentlySelectedOption.removeAttribute('selected'); if (self.hasOption(value)) { self.removeUnknownOption(); var hashedVal = hashKey(value); $element.val(hashedVal in self.selectValueMap ? hashedVal : value); var selectedOption = $element[0].options[$element[0].selectedIndex]; setOptionAsSelected(jqLite(selectedOption)); } else { if (value == null && self.emptyOption) { self.removeUnknownOption(); self.selectEmptyOption(); } else if (self.unknownOption.parent().length) { self.updateUnknownOption(value); } else { self.renderUnknownOption(value); } } }; self.addOption = function (value, element) { if (element[0].nodeType === NODE_TYPE_COMMENT) return; assertNotHasOwnProperty(value, '"option value"'); if (value === '') { self.hasEmptyOption = true; self.emptyOption = element; } var count = optionsMap.get(value) || 0; optionsMap.set(value, count + 1); scheduleRender(); }; self.removeOption = function (value) { var count = optionsMap.get(value); if (count) { if (count === 1) { optionsMap.delete(value); if (value === '') { self.hasEmptyOption = false; self.emptyOption = undefined; } } else { optionsMap.set(value, count - 1); } } }; self.hasOption = function (value) { return !!optionsMap.get(value); }; var renderScheduled = false; function scheduleRender() { if (renderScheduled) return; renderScheduled = true; $scope.$$postDigest(function () { renderScheduled = false; self.ngModelCtrl.$render(); }); } var updateScheduled = false; function scheduleViewValueUpdate(renderAfter) { if (updateScheduled) return; updateScheduled = true; $scope.$$postDigest(function () { if ($scope.$$destroyed) return; updateScheduled = false; self.ngModelCtrl.$setViewValue(self.readValue()); if (renderAfter) self.ngModelCtrl.$render(); }); } self.registerOption = function (optionScope, optionElement, optionAttrs, interpolateValueFn, interpolateTextFn) { if (optionAttrs.$attr.ngValue) { var oldVal, hashedVal = NaN; optionAttrs.$observe('value', function valueAttributeObserveAction(newVal) { var removal; var previouslySelected = optionElement.prop('selected'); if (isDefined(hashedVal)) { self.removeOption(oldVal); delete self.selectValueMap[hashedVal]; removal = true; } hashedVal = hashKey(newVal); oldVal = newVal; self.selectValueMap[hashedVal] = newVal; self.addOption(newVal, optionElement); optionElement.attr('value', hashedVal); if (removal && previouslySelected) { scheduleViewValueUpdate(); } }); } else if (interpolateValueFn) { optionAttrs.$observe('value', function valueAttributeObserveAction(newVal) { self.readValue(); var removal; var previouslySelected = optionElement.prop('selected'); if (isDefined(oldVal)) { self.removeOption(oldVal); removal = true; } oldVal = newVal; self.addOption(newVal, optionElement); if (removal && previouslySelected) { scheduleViewValueUpdate(); } }); } else if (interpolateTextFn) { optionScope.$watch(interpolateTextFn, function interpolateWatchAction(newVal, oldVal) { optionAttrs.$set('value', newVal); var previouslySelected = optionElement.prop('selected'); if (oldVal !== newVal) { self.removeOption(oldVal); } self.addOption(newVal, optionElement); if (oldVal && previouslySelected) { scheduleViewValueUpdate(); } }); } else { self.addOption(optionAttrs.value, optionElement); } optionAttrs.$observe('disabled', function (newVal) { if (newVal === 'true' || newVal && optionElement.prop('selected')) { if (self.multiple) { scheduleViewValueUpdate(true); } else { self.ngModelCtrl.$setViewValue(null); self.ngModelCtrl.$render(); } } }); optionElement.on('$destroy', function () { var currentValue = self.readValue(); var removeValue = optionAttrs.value; self.removeOption(removeValue); scheduleRender(); if (self.multiple && currentValue && currentValue.indexOf(removeValue) !== -1 || currentValue === removeValue) { scheduleViewValueUpdate(true); } }); }; function setOptionAsSelected(optionEl) { optionEl.prop('selected', true); optionEl.attr('selected', true); } }]

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions