Drop support for old browsers and some jQuery

This commit is contained in:
djmaze 2020-09-17 16:40:43 +02:00
parent 091c4ec811
commit d06fed09d6
38 changed files with 6137 additions and 872 deletions

View file

@ -1,8 +1,8 @@
(function () {
// Hide or don't minify context properties, see https://github.com/knockout/knockout/issues/2294
var contextSubscribable = ko.utils.createSymbolOrString('_subscribable');
var contextAncestorBindingInfo = ko.utils.createSymbolOrString('_ancestorBindingInfo');
var contextDataDependency = ko.utils.createSymbolOrString('_dataDependency');
var contextSubscribable = Symbol('_subscribable');
var contextAncestorBindingInfo = Symbol('_ancestorBindingInfo');
var contextDataDependency = Symbol('_dataDependency');
ko.bindingHandlers = {};
@ -565,11 +565,6 @@
};
ko.applyBindings = function (viewModelOrBindingContext, rootNode, extendContextCallback) {
// If jQuery is loaded after Knockout, we won't initially have access to it. So save it here.
if (!jQueryInstance && window['jQuery']) {
jQueryInstance = window['jQuery'];
}
if (arguments.length < 2) {
rootNode = document.body;
if (!rootNode) {

14
vendors/knockout/src/binding/defaultBindings/attr.js vendored Executable file → Normal file
View file

@ -19,17 +19,7 @@ ko.bindingHandlers['attr'] = {
attrValue = attrValue.toString();
}
// In IE <= 7 and IE8 Quirks Mode, you have to use the JavaScript property name instead of the
// HTML attribute name for certain attributes. IE8 Standards Mode supports the correct behavior,
// but instead of figuring out the mode, we'll just set the attribute through the JavaScript
// property for IE <= 8.
if (ko.utils.ieVersion <= 8 && attrName in attrHtmlToJavaScriptMap) {
attrName = attrHtmlToJavaScriptMap[attrName];
if (toRemove)
element.removeAttribute(attrName);
else
element[attrName] = attrValue;
} else if (!toRemove) {
if (!toRemove) {
namespace ? element.setAttributeNS(namespace, attrName, attrValue) : element.setAttribute(attrName, attrValue);
}
@ -38,7 +28,7 @@ ko.bindingHandlers['attr'] = {
// Deliberately being case-sensitive here because XHTML would regard "Name" as a different thing
// entirely, and there's no strong reason to allow for such casing in HTML.
if (attrName === "name") {
ko.utils.setElementName(element, toRemove ? "" : attrValue);
element.name = toRemove ? "" : attrValue;
}
});
}

19
vendors/knockout/src/binding/defaultBindings/checked.js vendored Executable file → Normal file
View file

@ -1,5 +1,16 @@
(function() {
function addOrRemoveItem(array, value, included) {
var existingEntryIndex = ko.utils.arrayIndexOf(ko.utils.peekObservable(array), value);
if (existingEntryIndex < 0) {
if (included)
array.push(value);
} else {
if (!included)
array.splice(existingEntryIndex, 1);
}
}
ko.bindingHandlers['checked'] = {
'after': ['value', 'attr'],
'init': function (element, valueAccessor, allBindings) {
@ -45,13 +56,13 @@ ko.bindingHandlers['checked'] = {
// currently checked, replace the old elem value with the new elem value
// in the model array.
if (isChecked) {
ko.utils.addOrRemoveItem(writableValue, elemValue, true);
ko.utils.addOrRemoveItem(writableValue, saveOldValue, false);
addOrRemoveItem(writableValue, elemValue, true);
addOrRemoveItem(writableValue, saveOldValue, false);
}
} else {
// When we're responding to the user having checked/unchecked a checkbox,
// add/remove the element value to the model array.
ko.utils.addOrRemoveItem(writableValue, elemValue, isChecked);
addOrRemoveItem(writableValue, elemValue, isChecked);
}
if (rawValueIsNonArrayObservable && ko.isWriteableObservable(modelValue)) {
@ -127,4 +138,4 @@ ko.bindingHandlers['checkedValue'] = {
}
};
})();
})();

0
vendors/knockout/src/binding/defaultBindings/click.js vendored Executable file → Normal file
View file

18
vendors/knockout/src/binding/defaultBindings/css.js vendored Executable file → Normal file
View file

@ -1,10 +1,22 @@
var classesWrittenByBindingKey = '__ko__cssValue';
// For details on the pattern for changing node classes
// see: https://github.com/knockout/knockout/issues/1597
function toggleDomNodeCssClass(node, classNames, shouldHaveClass) {
if (classNames) {
var addOrRemoveFn = shouldHaveClass ? 'add' : 'remove';
classNames.split(/\s+/).forEach(function(className) {
node.classList[addOrRemoveFn](className);
});
}
}
ko.bindingHandlers['class'] = {
'update': function (element, valueAccessor) {
var value = ko.utils.stringTrim(ko.utils.unwrapObservable(valueAccessor()));
ko.utils.toggleDomNodeCssClass(element, element[classesWrittenByBindingKey], false);
toggleDomNodeCssClass(element, element[classesWrittenByBindingKey], false);
element[classesWrittenByBindingKey] = value;
ko.utils.toggleDomNodeCssClass(element, value, true);
toggleDomNodeCssClass(element, value, true);
}
};
@ -14,7 +26,7 @@ ko.bindingHandlers['css'] = {
if (value !== null && typeof value == "object") {
ko.utils.objectForEach(value, function(className, shouldHaveClass) {
shouldHaveClass = ko.utils.unwrapObservable(shouldHaveClass);
ko.utils.toggleDomNodeCssClass(element, className, shouldHaveClass);
toggleDomNodeCssClass(element, className, shouldHaveClass);
});
} else {
ko.bindingHandlers['class']['update'](element, valueAccessor);

0
vendors/knockout/src/binding/defaultBindings/enableDisable.js vendored Executable file → Normal file
View file

0
vendors/knockout/src/binding/defaultBindings/event.js vendored Executable file → Normal file
View file

0
vendors/knockout/src/binding/defaultBindings/foreach.js vendored Executable file → Normal file
View file

16
vendors/knockout/src/binding/defaultBindings/hasfocus.js vendored Executable file → Normal file
View file

@ -10,17 +10,7 @@ ko.bindingHandlers['hasfocus'] = {
// from calling 'blur()' on the element when it loses focus.
// Discussion at https://github.com/SteveSanderson/knockout/pull/352
element[hasfocusUpdatingProperty] = true;
var ownerDoc = element.ownerDocument;
if ("activeElement" in ownerDoc) {
var active;
try {
active = ownerDoc.activeElement;
} catch(e) {
// IE9 throws if you access activeElement during page load (see issue #703)
active = ownerDoc.body;
}
isFocused = (active === element);
}
isFocused = (element.ownerDocument.activeElement === element);
var modelValue = valueAccessor();
ko.expressionRewriting.writeValueToProperty(modelValue, allBindings, 'hasfocus', isFocused, true);
@ -32,9 +22,9 @@ ko.bindingHandlers['hasfocus'] = {
var handleElementFocusOut = handleElementFocusChange.bind(null, false);
ko.utils.registerEventHandler(element, "focus", handleElementFocusIn);
ko.utils.registerEventHandler(element, "focusin", handleElementFocusIn); // For IE
ko.utils.registerEventHandler(element, "focusin", handleElementFocusIn);
ko.utils.registerEventHandler(element, "blur", handleElementFocusOut);
ko.utils.registerEventHandler(element, "focusout", handleElementFocusOut); // For IE
ko.utils.registerEventHandler(element, "focusout", handleElementFocusOut);
// Assume element is not focused (prevents "blur" being called initially)
element[hasfocusLastValue] = false;

0
vendors/knockout/src/binding/defaultBindings/html.js vendored Executable file → Normal file
View file

0
vendors/knockout/src/binding/defaultBindings/ifIfnotWith.js vendored Executable file → Normal file
View file

7
vendors/knockout/src/binding/defaultBindings/options.js vendored Executable file → Normal file
View file

@ -30,7 +30,7 @@ ko.bindingHandlers['options'] = {
if (!valueAllowUnset) {
if (multiple) {
previousSelectedValues = ko.utils.arrayMap(selectedOptions(), ko.selectExtensions.readValue);
previousSelectedValues = selectedOptions().map(ko.selectExtensions.readValue);
} else if (element.selectedIndex >= 0) {
previousSelectedValues.push(ko.selectExtensions.readValue(element.options[element.selectedIndex]));
}
@ -108,7 +108,7 @@ ko.bindingHandlers['options'] = {
// IE6 doesn't like us to assign selection to OPTION nodes before they're added to the document.
// That's why we first added them without selection. Now it's time to set the selection.
var isSelected = ko.utils.arrayIndexOf(previousSelectedValues, ko.selectExtensions.readValue(newOptions[0])) >= 0;
ko.utils.setOptionNodeSelectionState(newOptions[0], isSelected);
newOptions[0].selected = isSelected;
// If this option was changed from being selected during a single-item update, notify the change
if (itemUpdate && !isSelected) {
@ -154,9 +154,6 @@ ko.bindingHandlers['options'] = {
ko.bindingEvent.notify(element, ko.bindingEvent.childrenComplete);
}
// Workaround for IE bug
ko.utils.ensureSelectElementIsRenderedCorrectly(element);
if (previousScrollTop && Math.abs(previousScrollTop - element.scrollTop) > 20)
element.scrollTop = previousScrollTop;
}

2
vendors/knockout/src/binding/defaultBindings/selectedOptions.js vendored Executable file → Normal file
View file

@ -17,7 +17,7 @@ ko.bindingHandlers['selectedOptions'] = {
ko.utils.arrayForEach(element.getElementsByTagName("option"), function(node) {
var isSelected = ko.utils.arrayIndexOf(newValue, ko.selectExtensions.readValue(node)) >= 0;
if (node.selected != isSelected) { // This check prevents flashing of the select element in IE
ko.utils.setOptionNodeSelectionState(node, isSelected);
node.selected = isSelected;
}
});
}

4
vendors/knockout/src/binding/defaultBindings/style.js vendored Executable file → Normal file
View file

@ -9,9 +9,7 @@ ko.bindingHandlers['style'] = {
styleValue = "";
}
if (jQueryInstance) {
jQueryInstance(element)['css'](styleName, styleValue);
} else if (/^--/.test(styleName)) {
if (/^--/.test(styleName)) {
// Is styleName a custom CSS property?
element.style.setProperty(styleName, styleValue);
} else {

0
vendors/knockout/src/binding/defaultBindings/submit.js vendored Executable file → Normal file
View file

0
vendors/knockout/src/binding/defaultBindings/text.js vendored Executable file → Normal file
View file

View file

@ -1,51 +1,5 @@
(function () {
if (window && window.navigator) {
var parseVersion = function (matches) {
if (matches) {
return parseFloat(matches[1]);
}
};
// Detect various browser versions because some old versions don't fully support the 'input' event
var userAgent = window.navigator.userAgent,
operaVersion, chromeVersion, safariVersion, firefoxVersion, ieVersion, edgeVersion;
(operaVersion = window.opera && window.opera.version && parseInt(window.opera.version()))
|| (edgeVersion = parseVersion(userAgent.match(/Edge\/([^ ]+)$/)))
|| (chromeVersion = parseVersion(userAgent.match(/Chrome\/([^ ]+)/)))
|| (safariVersion = parseVersion(userAgent.match(/Version\/([^ ]+) Safari/)))
|| (firefoxVersion = parseVersion(userAgent.match(/Firefox\/([^ ]+)/)))
|| (ieVersion = ko.utils.ieVersion || parseVersion(userAgent.match(/MSIE ([^ ]+)/))) // Detects up to IE 10
|| (ieVersion = parseVersion(userAgent.match(/rv:([^ )]+)/))); // Detects IE 11
}
// IE 8 and 9 have bugs that prevent the normal events from firing when the value changes.
// But it does fire the 'selectionchange' event on many of those, presumably because the
// cursor is moving and that counts as the selection changing. The 'selectionchange' event is
// fired at the document level only and doesn't directly indicate which element changed. We
// set up just one event handler for the document and use 'activeElement' to determine which
// element was changed.
if (ieVersion >= 8 && ieVersion < 10) {
var selectionChangeRegisteredName = ko.utils.domData.nextKey(),
selectionChangeHandlerName = ko.utils.domData.nextKey();
var selectionChangeHandler = function(event) {
var target = this.activeElement,
handler = target && ko.utils.domData.get(target, selectionChangeHandlerName);
if (handler) {
handler(event);
}
};
var registerForSelectionChangeEvent = function (element, handler) {
var ownerDoc = element.ownerDocument;
if (!ko.utils.domData.get(ownerDoc, selectionChangeRegisteredName)) {
ko.utils.domData.set(ownerDoc, selectionChangeRegisteredName, true);
ko.utils.registerEventHandler(ownerDoc, 'selectionchange', selectionChangeHandler);
}
ko.utils.domData.set(element, selectionChangeHandlerName, handler);
};
}
ko.bindingHandlers['textInput'] = {
'init': function (element, valueAccessor, allBindings) {
@ -80,8 +34,7 @@ ko.bindingHandlers['textInput'] = {
// IE9 will mess up the DOM if you handle events synchronously which results in DOM changes (such as other bindings);
// so we'll make sure all updates are asynchronous
var ieUpdateModel = ko.utils.ieVersion == 9 ? deferUpdateModel : updateModel,
ourUpdate = false;
var ourUpdate = false;
var updateView = function () {
var modelValue = ko.utils.unwrapObservable(valueAccessor());
@ -119,66 +72,7 @@ ko.bindingHandlers['textInput'] = {
}
});
} else {
if (ieVersion) {
// All versions (including 11) of Internet Explorer have a bug that they don't generate an input or propertychange event when ESC is pressed
onEvent('keypress', updateModel);
}
if (ieVersion < 11) {
// Internet Explorer <= 8 doesn't support the 'input' event, but does include 'propertychange' that fires whenever
// any property of an element changes. Unlike 'input', it also fires if a property is changed from JavaScript code,
// but that's an acceptable compromise for this binding. IE 9 and 10 support 'input', but since they don't always
// fire it when using autocomplete, we'll use 'propertychange' for them also.
onEvent('propertychange', function(event) {
if (!ourUpdate && event.propertyName === 'value') {
ieUpdateModel(event);
}
});
}
if (ieVersion == 8) {
// IE 8 has a bug where it fails to fire 'propertychange' on the first update following a value change from
// JavaScript code. It also doesn't fire if you clear the entire value. To fix this, we bind to the following
// events too.
onEvent('keyup', updateModel); // A single keystoke
onEvent('keydown', updateModel); // The first character when a key is held down
}
if (registerForSelectionChangeEvent) {
// Internet Explorer 9 doesn't fire the 'input' event when deleting text, including using
// the backspace, delete, or ctrl-x keys, clicking the 'x' to clear the input, dragging text
// out of the field, and cutting or deleting text using the context menu. 'selectionchange'
// can detect all of those except dragging text out of the field, for which we use 'dragend'.
// These are also needed in IE8 because of the bug described above.
registerForSelectionChangeEvent(element, ieUpdateModel); // 'selectionchange' covers cut, paste, drop, delete, etc.
onEvent('dragend', deferUpdateModel);
}
if (!ieVersion || ieVersion >= 9) {
// All other supported browsers support the 'input' event, which fires whenever the content of the element is changed
// through the user interface.
onEvent('input', ieUpdateModel);
}
if (safariVersion < 5 && ko.utils.tagNameLower(element) === "textarea") {
// Safari <5 doesn't fire the 'input' event for <textarea> elements (it does fire 'textInput'
// but only when typing). So we'll just catch as much as we can with keydown, cut, and paste.
onEvent('keydown', deferUpdateModel);
onEvent('paste', deferUpdateModel);
onEvent('cut', deferUpdateModel);
} else if (operaVersion < 11) {
// Opera 10 doesn't always fire the 'input' event for cut, paste, undo & drop operations.
// We can try to catch some of those using 'keydown'.
onEvent('keydown', deferUpdateModel);
} else if (firefoxVersion < 4.0) {
// Firefox <= 3.6 doesn't fire the 'input' event when text is filled in through autocomplete
onEvent('DOMAutoComplete', updateModel);
// Firefox <=3.5 doesn't fire the 'input' event when text is dropped into the input.
onEvent('dragdrop', updateModel); // <3.5
onEvent('drop', updateModel); // 3.5
} else if (edgeVersion && element.type === "number") {
// Microsoft Edge doesn't fire 'input' or 'change' events for number inputs when
// the value is changed via the up / down arrow keys
onEvent('keydown', deferUpdateModel);
}
onEvent('input', updateModel);
}
// Bind to the change event so that we can catch programmatic updates of the value that fire this event.
@ -200,4 +94,4 @@ ko.bindingHandlers['textinput'] = {
}
};
})();
})();

3
vendors/knockout/src/binding/defaultBindings/uniqueName.js vendored Executable file → Normal file
View file

@ -1,8 +1,7 @@
ko.bindingHandlers['uniqueName'] = {
'init': function (element, valueAccessor) {
if (valueAccessor()) {
var name = "ko_unique_" + (++ko.bindingHandlers['uniqueName'].currentIndex);
ko.utils.setElementName(element, name);
element.name = "ko_unique_" + (++ko.bindingHandlers['uniqueName'].currentIndex);
}
}
};

20
vendors/knockout/src/binding/defaultBindings/value.js vendored Executable file → Normal file
View file

@ -11,7 +11,6 @@ ko.bindingHandlers['value'] = {
var eventsToCatch = [];
var requestedEventsToCatch = allBindings.get("valueUpdate");
var propertyChangedFired = false;
var elementValueBeforeEvent = null;
if (requestedEventsToCatch) {
@ -19,33 +18,20 @@ ko.bindingHandlers['value'] = {
if (typeof requestedEventsToCatch == "string") {
eventsToCatch = [requestedEventsToCatch];
} else {
eventsToCatch = ko.utils.arrayGetDistinctValues(requestedEventsToCatch);
eventsToCatch = requestedEventsToCatch ? requestedEventsToCatch.filter(function(item, index) {
return requestedEventsToCatch.indexOf(item) === index;
}) : [];
}
ko.utils.arrayRemoveItem(eventsToCatch, "change"); // We'll subscribe to "change" events later
}
var valueUpdateHandler = function() {
elementValueBeforeEvent = null;
propertyChangedFired = false;
var modelValue = valueAccessor();
var elementValue = ko.selectExtensions.readValue(element);
ko.expressionRewriting.writeValueToProperty(modelValue, allBindings, 'value', elementValue);
}
// Workaround for https://github.com/SteveSanderson/knockout/issues/122
// IE doesn't fire "change" events on textboxes if the user selects a value from its autocomplete list
var ieAutoCompleteHackNeeded = ko.utils.ieVersion && isInputElement && element.type == "text"
&& element.autocomplete != "off" && (!element.form || element.form.autocomplete != "off");
if (ieAutoCompleteHackNeeded && ko.utils.arrayIndexOf(eventsToCatch, "propertychange") == -1) {
ko.utils.registerEventHandler(element, "propertychange", function () { propertyChangedFired = true });
ko.utils.registerEventHandler(element, "focus", function () { propertyChangedFired = false });
ko.utils.registerEventHandler(element, "blur", function() {
if (propertyChangedFired) {
valueUpdateHandler();
}
});
}
ko.utils.arrayForEach(eventsToCatch, function(eventName) {
// The syntax "after<eventname>" means "run the handler asynchronously after the event"
// This is useful, for example, to catch "keydown" events after the browser has updated the control

0
vendors/knockout/src/binding/defaultBindings/visibleHidden.js vendored Executable file → Normal file
View file

View file

@ -88,7 +88,7 @@
} else {
if (!editScript || (lastMappingResult && lastMappingResult['_countWaitingForRemove'])) {
// Compare the provided array against the previous one
var lastArray = ko.utils.arrayMap(lastMappingResult, function (x) { return x.arrayEntry; }),
var lastArray = Array.prototype.map.call(lastMappingResult, function (x) { return x.arrayEntry; }),
compareOptions = {
'dontLimitMoves': options['dontLimitMoves'],
'sparse': true

View file

@ -10,9 +10,7 @@
case 'option':
if (element[hasDomDataExpandoProperty] === true)
return ko.utils.domData.get(element, ko.bindingHandlers.options.optionValueDomDataKey);
return ko.utils.ieVersion <= 7
? (element.getAttributeNode('value') && element.getAttributeNode('value').specified ? element.value : element.text)
: element.value;
return element.value;
case 'select':
return element.selectedIndex >= 0 ? ko.selectExtensions.readValue(element.options[element.selectedIndex]) : undefined;
default:
@ -53,14 +51,6 @@
}
if (allowUnset || selection >= 0 || (value === undefined && element.size > 1)) {
element.selectedIndex = selection;
if (ko.utils.ieVersion === 6) {
// Workaround for IE6 bug: It won't reliably apply values to SELECT nodes during the same execution thread
// right after you've changed the set of OPTION nodes on it. So for that node type, we'll schedule a second thread
// to apply the value as well.
ko.utils.setTimeout(function () {
element.selectedIndex = selection;
}, 0);
}
}
break;
default: