mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-03 14:37:02 +03:00
Drop support for old browsers and some jQuery
This commit is contained in:
parent
091c4ec811
commit
d06fed09d6
38 changed files with 6137 additions and 872 deletions
|
|
@ -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
14
vendors/knockout/src/binding/defaultBindings/attr.js
vendored
Executable file → Normal 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
19
vendors/knockout/src/binding/defaultBindings/checked.js
vendored
Executable file → Normal 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
0
vendors/knockout/src/binding/defaultBindings/click.js
vendored
Executable file → Normal file
18
vendors/knockout/src/binding/defaultBindings/css.js
vendored
Executable file → Normal file
18
vendors/knockout/src/binding/defaultBindings/css.js
vendored
Executable file → Normal 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
0
vendors/knockout/src/binding/defaultBindings/enableDisable.js
vendored
Executable file → Normal file
0
vendors/knockout/src/binding/defaultBindings/event.js
vendored
Executable file → Normal file
0
vendors/knockout/src/binding/defaultBindings/event.js
vendored
Executable file → Normal file
0
vendors/knockout/src/binding/defaultBindings/foreach.js
vendored
Executable file → Normal file
0
vendors/knockout/src/binding/defaultBindings/foreach.js
vendored
Executable file → Normal file
16
vendors/knockout/src/binding/defaultBindings/hasfocus.js
vendored
Executable file → Normal file
16
vendors/knockout/src/binding/defaultBindings/hasfocus.js
vendored
Executable file → Normal 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
0
vendors/knockout/src/binding/defaultBindings/html.js
vendored
Executable file → Normal file
0
vendors/knockout/src/binding/defaultBindings/ifIfnotWith.js
vendored
Executable file → Normal file
0
vendors/knockout/src/binding/defaultBindings/ifIfnotWith.js
vendored
Executable file → Normal file
7
vendors/knockout/src/binding/defaultBindings/options.js
vendored
Executable file → Normal file
7
vendors/knockout/src/binding/defaultBindings/options.js
vendored
Executable file → Normal 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
2
vendors/knockout/src/binding/defaultBindings/selectedOptions.js
vendored
Executable file → Normal 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
4
vendors/knockout/src/binding/defaultBindings/style.js
vendored
Executable file → Normal 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
0
vendors/knockout/src/binding/defaultBindings/submit.js
vendored
Executable file → Normal file
0
vendors/knockout/src/binding/defaultBindings/text.js
vendored
Executable file → Normal file
0
vendors/knockout/src/binding/defaultBindings/text.js
vendored
Executable file → Normal 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
3
vendors/knockout/src/binding/defaultBindings/uniqueName.js
vendored
Executable file → Normal 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
20
vendors/knockout/src/binding/defaultBindings/value.js
vendored
Executable file → Normal 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
0
vendors/knockout/src/binding/defaultBindings/visibleHidden.js
vendored
Executable file → Normal 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
|
||||
|
|
|
|||
12
vendors/knockout/src/binding/selectExtensions.js
vendored
12
vendors/knockout/src/binding/selectExtensions.js
vendored
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
var tagNameLower = ko.utils.tagNameLower(node);
|
||||
if (ko.components.isRegistered(tagNameLower)) {
|
||||
// Try to determine that this node can be considered a *custom* element; see https://github.com/knockout/knockout/issues/1603
|
||||
if (tagNameLower.indexOf('-') != -1 || ('' + node) == "[object HTMLUnknownElement]" || (ko.utils.ieVersion <= 8 && node.tagName === tagNameLower)) {
|
||||
if (tagNameLower.indexOf('-') != -1 || ('' + node) == "[object HTMLUnknownElement]") {
|
||||
return tagNameLower;
|
||||
}
|
||||
}
|
||||
|
|
@ -84,32 +84,4 @@
|
|||
return { '$raw': {} };
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// Compatibility code for older (pre-HTML5) IE browsers
|
||||
|
||||
if (ko.utils.ieVersion < 9) {
|
||||
// Whenever you preregister a component, enable it as a custom element in the current document
|
||||
ko.components['register'] = (function(originalFunction) {
|
||||
return function(componentName) {
|
||||
document.createElement(componentName); // Allows IE<9 to parse markup containing the custom element
|
||||
return originalFunction.apply(this, arguments);
|
||||
}
|
||||
})(ko.components['register']);
|
||||
|
||||
// Whenever you create a document fragment, enable all preregistered component names as custom elements
|
||||
// This is needed to make innerShiv/jQuery HTML parsing correctly handle the custom elements
|
||||
document.createDocumentFragment = (function(originalFunction) {
|
||||
return function() {
|
||||
var newDocFrag = originalFunction(),
|
||||
allComponents = ko.components._allRegisteredComponents;
|
||||
for (var componentName in allComponents) {
|
||||
if (Object.prototype.hasOwnProperty.call(allComponents, componentName)) {
|
||||
newDocFrag.createElement(componentName);
|
||||
}
|
||||
}
|
||||
return newDocFrag;
|
||||
};
|
||||
})(document.createDocumentFragment);
|
||||
}
|
||||
})();
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
var computedState = ko.utils.createSymbolOrString('_state');
|
||||
var computedState = Symbol('_state');
|
||||
|
||||
ko.computed = ko.dependentObservable = function (evaluatorFunctionOrOptions, evaluatorFunctionTarget, options) {
|
||||
if (typeof evaluatorFunctionOrOptions === "object") {
|
||||
|
|
|
|||
|
|
@ -1,96 +0,0 @@
|
|||
|
||||
(function() {
|
||||
var maxNestedObservableDepth = 10; // Escape the (unlikely) pathological case where an observable's current value is itself (or similar reference cycle)
|
||||
|
||||
ko.toJS = function(rootObject) {
|
||||
if (arguments.length == 0)
|
||||
throw new Error("When calling ko.toJS, pass the object you want to convert.");
|
||||
|
||||
// We just unwrap everything at every level in the object graph
|
||||
return mapJsObjectGraph(rootObject, function(valueToMap) {
|
||||
// Loop because an observable's value might in turn be another observable wrapper
|
||||
for (var i = 0; ko.isObservable(valueToMap) && (i < maxNestedObservableDepth); i++)
|
||||
valueToMap = valueToMap();
|
||||
return valueToMap;
|
||||
});
|
||||
};
|
||||
|
||||
ko.toJSON = function(rootObject, replacer, space) { // replacer and space are optional
|
||||
var plainJavaScriptObject = ko.toJS(rootObject);
|
||||
return ko.utils.stringifyJson(plainJavaScriptObject, replacer, space);
|
||||
};
|
||||
|
||||
function mapJsObjectGraph(rootObject, mapInputCallback, visitedObjects) {
|
||||
visitedObjects = visitedObjects || new objectLookup();
|
||||
|
||||
rootObject = mapInputCallback(rootObject);
|
||||
var canHaveProperties = (typeof rootObject == "object") && (rootObject !== null) && (rootObject !== undefined) && (!(rootObject instanceof RegExp)) && (!(rootObject instanceof Date)) && (!(rootObject instanceof String)) && (!(rootObject instanceof Number)) && (!(rootObject instanceof Boolean));
|
||||
if (!canHaveProperties)
|
||||
return rootObject;
|
||||
|
||||
var outputProperties = rootObject instanceof Array ? [] : {};
|
||||
visitedObjects.save(rootObject, outputProperties);
|
||||
|
||||
visitPropertiesOrArrayEntries(rootObject, function(indexer) {
|
||||
var propertyValue = mapInputCallback(rootObject[indexer]);
|
||||
|
||||
switch (typeof propertyValue) {
|
||||
case "boolean":
|
||||
case "number":
|
||||
case "string":
|
||||
case "function":
|
||||
outputProperties[indexer] = propertyValue;
|
||||
break;
|
||||
case "object":
|
||||
case "undefined":
|
||||
var previouslyMappedValue = visitedObjects.get(propertyValue);
|
||||
outputProperties[indexer] = (previouslyMappedValue !== undefined)
|
||||
? previouslyMappedValue
|
||||
: mapJsObjectGraph(propertyValue, mapInputCallback, visitedObjects);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
return outputProperties;
|
||||
}
|
||||
|
||||
function visitPropertiesOrArrayEntries(rootObject, visitorCallback) {
|
||||
if (rootObject instanceof Array) {
|
||||
for (var i = 0; i < rootObject.length; i++)
|
||||
visitorCallback(i);
|
||||
|
||||
// For arrays, also respect toJSON property for custom mappings (fixes #278)
|
||||
if (typeof rootObject['toJSON'] == 'function')
|
||||
visitorCallback('toJSON');
|
||||
} else {
|
||||
for (var propertyName in rootObject) {
|
||||
visitorCallback(propertyName);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function objectLookup() {
|
||||
this.keys = [];
|
||||
this.values = [];
|
||||
};
|
||||
|
||||
objectLookup.prototype = {
|
||||
constructor: objectLookup,
|
||||
save: function(key, value) {
|
||||
var existingIndex = ko.utils.arrayIndexOf(this.keys, key);
|
||||
if (existingIndex >= 0)
|
||||
this.values[existingIndex] = value;
|
||||
else {
|
||||
this.keys.push(key);
|
||||
this.values.push(value);
|
||||
}
|
||||
},
|
||||
get: function(key) {
|
||||
var existingIndex = ko.utils.arrayIndexOf(this.keys, key);
|
||||
return (existingIndex >= 0) ? this.values[existingIndex] : undefined;
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
ko.exportSymbol('toJS', ko.toJS);
|
||||
ko.exportSymbol('toJSON', ko.toJSON);
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
var observableLatestValue = ko.utils.createSymbolOrString('_latestValue');
|
||||
var observableLatestValue = Symbol('_latestValue');
|
||||
|
||||
ko.observable = function (initialValue) {
|
||||
function observable() {
|
||||
|
|
|
|||
|
|
@ -12,11 +12,10 @@ ko.when = function(predicate, callback, context) {
|
|||
|
||||
return subscription;
|
||||
}
|
||||
if (typeof Promise === "function" && !callback) {
|
||||
return new Promise(kowhen);
|
||||
} else {
|
||||
if (callback) {
|
||||
return kowhen(callback.bind(context));
|
||||
}
|
||||
return new Promise(kowhen);
|
||||
};
|
||||
|
||||
ko.exportSymbol('when', ko.when);
|
||||
|
|
|
|||
|
|
@ -1,84 +0,0 @@
|
|||
(function() {
|
||||
ko.jqueryTmplTemplateEngine = function () {
|
||||
// Detect which version of jquery-tmpl you're using. Unfortunately jquery-tmpl
|
||||
// doesn't expose a version number, so we have to infer it.
|
||||
// Note that as of Knockout 1.3, we only support jQuery.tmpl 1.0.0pre and later,
|
||||
// which KO internally refers to as version "2", so older versions are no longer detected.
|
||||
var jQueryTmplVersion = this.jQueryTmplVersion = (function() {
|
||||
if (!jQueryInstance || !(jQueryInstance['tmpl']))
|
||||
return 0;
|
||||
// Since it exposes no official version number, we use our own numbering system. To be updated as jquery-tmpl evolves.
|
||||
try {
|
||||
if (jQueryInstance['tmpl']['tag']['tmpl']['open'].toString().indexOf('__') >= 0) {
|
||||
// Since 1.0.0pre, custom tags should append markup to an array called "__"
|
||||
return 2; // Final version of jquery.tmpl
|
||||
}
|
||||
} catch(ex) { /* Apparently not the version we were looking for */ }
|
||||
|
||||
return 1; // Any older version that we don't support
|
||||
})();
|
||||
|
||||
function ensureHasReferencedJQueryTemplates() {
|
||||
if (jQueryTmplVersion < 2)
|
||||
throw new Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later.");
|
||||
}
|
||||
|
||||
function executeTemplate(compiledTemplate, data, jQueryTemplateOptions) {
|
||||
return jQueryInstance['tmpl'](compiledTemplate, data, jQueryTemplateOptions);
|
||||
}
|
||||
|
||||
this['renderTemplateSource'] = function(templateSource, bindingContext, options, templateDocument) {
|
||||
templateDocument = templateDocument || document;
|
||||
options = options || {};
|
||||
ensureHasReferencedJQueryTemplates();
|
||||
|
||||
// Ensure we have stored a precompiled version of this template (don't want to reparse on every render)
|
||||
var precompiled = templateSource['data']('precompiled');
|
||||
if (!precompiled) {
|
||||
var templateText = templateSource['text']() || "";
|
||||
// Wrap in "with($whatever.koBindingContext) { ... }"
|
||||
templateText = "{{ko_with $item.koBindingContext}}" + templateText + "{{/ko_with}}";
|
||||
|
||||
precompiled = jQueryInstance['template'](null, templateText);
|
||||
templateSource['data']('precompiled', precompiled);
|
||||
}
|
||||
|
||||
var data = [bindingContext['$data']]; // Prewrap the data in an array to stop jquery.tmpl from trying to unwrap any arrays
|
||||
var jQueryTemplateOptions = jQueryInstance['extend']({ 'koBindingContext': bindingContext }, options['templateOptions']);
|
||||
|
||||
var resultNodes = executeTemplate(precompiled, data, jQueryTemplateOptions);
|
||||
resultNodes['appendTo'](templateDocument.createElement("div")); // Using "appendTo" forces jQuery/jQuery.tmpl to perform necessary cleanup work
|
||||
|
||||
jQueryInstance['fragments'] = {}; // Clear jQuery's fragment cache to avoid a memory leak after a large number of template renders
|
||||
return resultNodes;
|
||||
};
|
||||
|
||||
this['createJavaScriptEvaluatorBlock'] = function(script) {
|
||||
return "{{ko_code ((function() { return " + script + " })()) }}";
|
||||
};
|
||||
|
||||
this['addTemplate'] = function(templateName, templateMarkup) {
|
||||
document.write("<script type='text/html' id='" + templateName + "'>" + templateMarkup + "<" + "/script>");
|
||||
};
|
||||
|
||||
if (jQueryTmplVersion > 0) {
|
||||
jQueryInstance['tmpl']['tag']['ko_code'] = {
|
||||
open: "__.push($1 || '');"
|
||||
};
|
||||
jQueryInstance['tmpl']['tag']['ko_with'] = {
|
||||
open: "with($1) {",
|
||||
close: "} "
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
ko.jqueryTmplTemplateEngine.prototype = new ko.templateEngine();
|
||||
ko.jqueryTmplTemplateEngine.prototype.constructor = ko.jqueryTmplTemplateEngine;
|
||||
|
||||
// Use this one by default *only if jquery.tmpl is referenced*
|
||||
var jqueryTmplTemplateEngineInstance = new ko.jqueryTmplTemplateEngine();
|
||||
if (jqueryTmplTemplateEngineInstance.jQueryTmplVersion > 0)
|
||||
ko.setTemplateEngine(jqueryTmplTemplateEngineInstance);
|
||||
|
||||
ko.exportSymbol('jqueryTmplTemplateEngine', ko.jqueryTmplTemplateEngine);
|
||||
})();
|
||||
|
|
@ -5,16 +5,13 @@ ko.nativeTemplateEngine = function () {
|
|||
ko.nativeTemplateEngine.prototype = new ko.templateEngine();
|
||||
ko.nativeTemplateEngine.prototype.constructor = ko.nativeTemplateEngine;
|
||||
ko.nativeTemplateEngine.prototype['renderTemplateSource'] = function (templateSource, bindingContext, options, templateDocument) {
|
||||
var useNodesIfAvailable = !(ko.utils.ieVersion < 9), // IE<9 cloneNode doesn't work properly
|
||||
templateNodesFunc = useNodesIfAvailable ? templateSource['nodes'] : null,
|
||||
templateNodes = templateNodesFunc ? templateSource['nodes']() : null;
|
||||
|
||||
var templateNodesFunc = templateSource.nodes,
|
||||
templateNodes = templateNodesFunc ? templateSource.nodes() : null;
|
||||
if (templateNodes) {
|
||||
return ko.utils.makeArray(templateNodes.cloneNode(true).childNodes);
|
||||
} else {
|
||||
var templateText = templateSource['text']();
|
||||
return ko.utils.parseHtmlFragment(templateText, templateDocument);
|
||||
}
|
||||
var templateText = templateSource['text']();
|
||||
return ko.utils.parseHtmlFragment(templateText, templateDocument);
|
||||
};
|
||||
|
||||
ko.nativeTemplateEngine.instance = new ko.nativeTemplateEngine();
|
||||
|
|
|
|||
62
vendors/knockout/src/utils.domData.js
vendored
62
vendors/knockout/src/utils.domData.js
vendored
|
|
@ -1,52 +1,26 @@
|
|||
|
||||
ko.utils.domData = new (function () {
|
||||
var uniqueId = 0;
|
||||
var dataStoreKeyExpandoPropertyName = "__ko__" + (new Date).getTime();
|
||||
var dataStore = {};
|
||||
var dataStoreKeyExpandoPropertyName = "__ko__" + (Date.now());
|
||||
|
||||
var getDataForNode, clear;
|
||||
if (!ko.utils.ieVersion) {
|
||||
// We considered using WeakMap, but it has a problem in IE 11 and Edge that prevents using
|
||||
// it cross-window, so instead we just store the data directly on the node.
|
||||
// See https://github.com/knockout/knockout/issues/2141
|
||||
getDataForNode = function (node, createIfNotFound) {
|
||||
var dataForNode = node[dataStoreKeyExpandoPropertyName];
|
||||
if (!dataForNode && createIfNotFound) {
|
||||
dataForNode = node[dataStoreKeyExpandoPropertyName] = {};
|
||||
}
|
||||
return dataForNode;
|
||||
};
|
||||
clear = function (node) {
|
||||
if (node[dataStoreKeyExpandoPropertyName]) {
|
||||
delete node[dataStoreKeyExpandoPropertyName];
|
||||
return true; // Exposing "did clean" flag purely so specs can infer whether things have been cleaned up as intended
|
||||
}
|
||||
return false;
|
||||
};
|
||||
} else {
|
||||
// Old IE versions have memory issues if you store objects on the node, so we use a
|
||||
// separate data storage and link to it from the node using a string key.
|
||||
getDataForNode = function (node, createIfNotFound) {
|
||||
var dataStoreKey = node[dataStoreKeyExpandoPropertyName];
|
||||
var hasExistingDataStore = dataStoreKey && (dataStoreKey !== "null") && dataStore[dataStoreKey];
|
||||
if (!hasExistingDataStore) {
|
||||
if (!createIfNotFound)
|
||||
return undefined;
|
||||
dataStoreKey = node[dataStoreKeyExpandoPropertyName] = "ko" + uniqueId++;
|
||||
dataStore[dataStoreKey] = {};
|
||||
}
|
||||
return dataStore[dataStoreKey];
|
||||
};
|
||||
clear = function (node) {
|
||||
var dataStoreKey = node[dataStoreKeyExpandoPropertyName];
|
||||
if (dataStoreKey) {
|
||||
delete dataStore[dataStoreKey];
|
||||
node[dataStoreKeyExpandoPropertyName] = null;
|
||||
return true; // Exposing "did clean" flag purely so specs can infer whether things have been cleaned up as intended
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
// We considered using WeakMap, but it has a problem in IE 11 and Edge that prevents using
|
||||
// it cross-window, so instead we just store the data directly on the node.
|
||||
// See https://github.com/knockout/knockout/issues/2141
|
||||
getDataForNode = function (node, createIfNotFound) {
|
||||
var dataForNode = node[dataStoreKeyExpandoPropertyName];
|
||||
if (!dataForNode && createIfNotFound) {
|
||||
dataForNode = node[dataStoreKeyExpandoPropertyName] = {};
|
||||
}
|
||||
return dataForNode;
|
||||
};
|
||||
clear = function (node) {
|
||||
if (node[dataStoreKeyExpandoPropertyName]) {
|
||||
delete node[dataStoreKeyExpandoPropertyName];
|
||||
return true; // Exposing "did clean" flag purely so specs can infer whether things have been cleaned up as intended
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
return {
|
||||
get: function (node, key) {
|
||||
|
|
|
|||
56
vendors/knockout/src/utils.domManipulation.js
vendored
56
vendors/knockout/src/utils.domManipulation.js
vendored
|
|
@ -13,10 +13,7 @@
|
|||
'th': tr,
|
||||
'option': select,
|
||||
'optgroup': select
|
||||
},
|
||||
|
||||
// This is needed for old IE if you're *not* using either jQuery or innerShiv. Doesn't affect other cases.
|
||||
mayRequireCreateElementHack = ko.utils.ieVersion <= 8;
|
||||
};
|
||||
|
||||
function getWrap(tags) {
|
||||
var m = tags.match(/^(?:<!--.*?-->\s*?)*?<([a-z]+)[\s>]/);
|
||||
|
|
@ -49,17 +46,7 @@
|
|||
// somehow shims the native APIs so it just works anyway)
|
||||
div.appendChild(windowContext['innerShiv'](markup));
|
||||
} else {
|
||||
if (mayRequireCreateElementHack) {
|
||||
// The document.createElement('my-element') trick to enable custom elements in IE6-8
|
||||
// only works if we assign innerHTML on an element associated with that document.
|
||||
documentContext.body.appendChild(div);
|
||||
}
|
||||
|
||||
div.innerHTML = markup;
|
||||
|
||||
if (mayRequireCreateElementHack) {
|
||||
div.parentNode.removeChild(div);
|
||||
}
|
||||
}
|
||||
|
||||
// Move to the right depth
|
||||
|
|
@ -69,35 +56,8 @@
|
|||
return ko.utils.makeArray(div.lastChild.childNodes);
|
||||
}
|
||||
|
||||
function jQueryHtmlParse(html, documentContext) {
|
||||
// jQuery's "parseHTML" function was introduced in jQuery 1.8.0 and is a documented public API.
|
||||
if (jQueryInstance['parseHTML']) {
|
||||
return jQueryInstance['parseHTML'](html, documentContext) || []; // Ensure we always return an array and never null
|
||||
} else {
|
||||
// For jQuery < 1.8.0, we fall back on the undocumented internal "clean" function.
|
||||
var elems = jQueryInstance['clean']([html], documentContext);
|
||||
|
||||
// As of jQuery 1.7.1, jQuery parses the HTML by appending it to some dummy parent nodes held in an in-memory document fragment.
|
||||
// Unfortunately, it never clears the dummy parent nodes from the document fragment, so it leaks memory over time.
|
||||
// Fix this by finding the top-most dummy parent element, and detaching it from its owner fragment.
|
||||
if (elems && elems[0]) {
|
||||
// Find the top-most parent element that's a direct child of a document fragment
|
||||
var elem = elems[0];
|
||||
while (elem.parentNode && elem.parentNode.nodeType !== 11 /* i.e., DocumentFragment */)
|
||||
elem = elem.parentNode;
|
||||
// ... then detach it
|
||||
if (elem.parentNode)
|
||||
elem.parentNode.removeChild(elem);
|
||||
}
|
||||
|
||||
return elems;
|
||||
}
|
||||
}
|
||||
|
||||
ko.utils.parseHtmlFragment = function(html, documentContext) {
|
||||
return jQueryInstance ?
|
||||
jQueryHtmlParse(html, documentContext) : // As below, benefit from jQuery's optimisations where possible
|
||||
simpleHtmlParse(html, documentContext); // ... otherwise, this simple logic will do in most common cases.
|
||||
return simpleHtmlParse(html, documentContext); // ... otherwise, this simple logic will do in most common cases.
|
||||
};
|
||||
|
||||
ko.utils.parseHtmlForTemplateNodes = function(html, documentContext) {
|
||||
|
|
@ -118,14 +78,10 @@
|
|||
// jQuery contains a lot of sophisticated code to parse arbitrary HTML fragments,
|
||||
// for example <tr> elements which are not normally allowed to exist on their own.
|
||||
// If you've referenced jQuery we'll use that rather than duplicating its code.
|
||||
if (jQueryInstance) {
|
||||
jQueryInstance(node)['html'](html);
|
||||
} else {
|
||||
// ... otherwise, use KO's own parsing logic.
|
||||
var parsedNodes = ko.utils.parseHtmlFragment(html, node.ownerDocument);
|
||||
for (var i = 0; i < parsedNodes.length; i++)
|
||||
node.appendChild(parsedNodes[i]);
|
||||
}
|
||||
// ... otherwise, use KO's own parsing logic.
|
||||
var parsedNodes = ko.utils.parseHtmlFragment(html, node.ownerDocument);
|
||||
for (var i = 0; i < parsedNodes.length; i++)
|
||||
node.appendChild(parsedNodes[i]);
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -88,12 +88,12 @@ ko.utils.domNodeDisposal = new (function () {
|
|||
node.parentNode.removeChild(node);
|
||||
},
|
||||
|
||||
"cleanExternalData" : function (node) {
|
||||
'cleanExternalData' : function (node) {
|
||||
// Special support for jQuery here because it's so commonly used.
|
||||
// Many jQuery plugins (including jquery.tmpl) store data using jQuery's equivalent of domData
|
||||
// so notify it to tear down any resources associated with the node & descendants here.
|
||||
if (jQueryInstance && (typeof jQueryInstance['cleanData'] == "function"))
|
||||
jQueryInstance['cleanData']([node]);
|
||||
if (jQuery && jQuery['cleanData'])
|
||||
jQuery['cleanData']([node]);
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
|
|
|||
397
vendors/knockout/src/utils.js
vendored
397
vendors/knockout/src/utils.js
vendored
|
|
@ -1,21 +1,15 @@
|
|||
ko.utils = (function () {
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
function objectForEach(obj, action) {
|
||||
for (var prop in obj) {
|
||||
if (hasOwnProperty.call(obj, prop)) {
|
||||
action(prop, obj[prop]);
|
||||
}
|
||||
}
|
||||
obj && Object.entries(obj).forEach(function(prop) {
|
||||
action(prop[0], prop[1]);
|
||||
});
|
||||
}
|
||||
|
||||
function extend(target, source) {
|
||||
if (source) {
|
||||
for(var prop in source) {
|
||||
if(hasOwnProperty.call(source, prop)) {
|
||||
target[prop] = source[prop];
|
||||
}
|
||||
}
|
||||
Object.entries(source).forEach(function(prop) {
|
||||
target[prop[0]] = prop[1];
|
||||
});
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
|
@ -26,98 +20,32 @@ ko.utils = (function () {
|
|||
}
|
||||
|
||||
var canSetPrototype = ({ __proto__: [] } instanceof Array);
|
||||
var canUseSymbols = !DEBUG && typeof Symbol === 'function';
|
||||
|
||||
// Represent the known event types in a compact way, then at runtime transform it into a hash with event name as key (for fast lookup)
|
||||
var knownEvents = {}, knownEventTypesByEventName = {};
|
||||
var keyEventTypeName = (navigator && /Firefox\/2/i.test(navigator.userAgent)) ? 'KeyboardEvent' : 'UIEvents';
|
||||
knownEvents[keyEventTypeName] = ['keyup', 'keydown', 'keypress'];
|
||||
knownEvents['MouseEvents'] = ['click', 'dblclick', 'mousedown', 'mouseup', 'mousemove', 'mouseover', 'mouseout', 'mouseenter', 'mouseleave'];
|
||||
objectForEach(knownEvents, function(eventType, knownEventsForType) {
|
||||
if (knownEventsForType.length) {
|
||||
for (var i = 0, j = knownEventsForType.length; i < j; i++)
|
||||
knownEventTypesByEventName[knownEventsForType[i]] = eventType;
|
||||
}
|
||||
});
|
||||
var eventsThatMustBeRegisteredUsingAttachEvent = { 'propertychange': true }; // Workaround for an IE9 issue - https://github.com/SteveSanderson/knockout/issues/406
|
||||
|
||||
// Detect IE versions for bug workarounds (uses IE conditionals, not UA string, for robustness)
|
||||
// Note that, since IE 10 does not support conditional comments, the following logic only detects IE < 10.
|
||||
// Currently this is by design, since IE 10+ behaves correctly when treated as a standard browser.
|
||||
// If there is a future need to detect specific versions of IE10+, we will amend this.
|
||||
var ieVersion = document && (function() {
|
||||
var version = 3, div = document.createElement('div'), iElems = div.getElementsByTagName('i');
|
||||
|
||||
// Keep constructing conditional HTML blocks until we hit one that resolves to an empty fragment
|
||||
while (
|
||||
div.innerHTML = '<!--[if gt IE ' + (++version) + ']><i></i><![endif]-->',
|
||||
iElems[0]
|
||||
) {}
|
||||
return version > 4 ? version : undefined;
|
||||
}());
|
||||
var isIe6 = ieVersion === 6,
|
||||
isIe7 = ieVersion === 7;
|
||||
var ke = 'KeyboardEvent', me = 'MouseEvent',
|
||||
knownEventTypesByEventName = {
|
||||
keyup: ke, keydown: ke, keypress: ke,
|
||||
click: me, dblclick: me, mousedown: me, mouseup: me, mousemove: me,
|
||||
mouseover: me, mouseout: me, mouseenter: me, mouseleave: me
|
||||
};
|
||||
|
||||
function isClickOnCheckableElement(element, eventType) {
|
||||
if ((ko.utils.tagNameLower(element) !== "input") || !element.type) return false;
|
||||
if ((element.nodeName !== "INPUT") || !element.type) return false;
|
||||
if (eventType.toLowerCase() != "click") return false;
|
||||
var inputType = element.type;
|
||||
return (inputType == "checkbox") || (inputType == "radio");
|
||||
}
|
||||
|
||||
// For details on the pattern for changing node classes
|
||||
// see: https://github.com/knockout/knockout/issues/1597
|
||||
var cssClassNameRegex = /\S+/g;
|
||||
|
||||
var jQueryEventAttachName;
|
||||
|
||||
function toggleDomNodeCssClass(node, classNames, shouldHaveClass) {
|
||||
var addOrRemoveFn;
|
||||
if (classNames) {
|
||||
if (typeof node.classList === 'object') {
|
||||
addOrRemoveFn = node.classList[shouldHaveClass ? 'add' : 'remove'];
|
||||
ko.utils.arrayForEach(classNames.match(cssClassNameRegex), function(className) {
|
||||
addOrRemoveFn.call(node.classList, className);
|
||||
});
|
||||
} else if (typeof node.className['baseVal'] === 'string') {
|
||||
// SVG tag .classNames is an SVGAnimatedString instance
|
||||
toggleObjectClassPropertyString(node.className, 'baseVal', classNames, shouldHaveClass);
|
||||
} else {
|
||||
// node.className ought to be a string.
|
||||
toggleObjectClassPropertyString(node, 'className', classNames, shouldHaveClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function toggleObjectClassPropertyString(obj, prop, classNames, shouldHaveClass) {
|
||||
// obj/prop is either a node/'className' or a SVGAnimatedString/'baseVal'.
|
||||
var currentClassNames = obj[prop].match(cssClassNameRegex) || [];
|
||||
ko.utils.arrayForEach(classNames.match(cssClassNameRegex), function(className) {
|
||||
ko.utils.addOrRemoveItem(currentClassNames, className, shouldHaveClass);
|
||||
});
|
||||
obj[prop] = currentClassNames.join(" ");
|
||||
}
|
||||
|
||||
return {
|
||||
fieldsIncludedWithJsonPost: ['authenticity_token', /^__RequestVerificationToken(_.*)?$/],
|
||||
|
||||
arrayForEach: function (array, action, actionOwner) {
|
||||
for (var i = 0, j = array.length; i < j; i++) {
|
||||
action.call(actionOwner, array[i], i, array);
|
||||
}
|
||||
},
|
||||
|
||||
arrayIndexOf: typeof Array.prototype.indexOf == "function"
|
||||
? function (array, item) {
|
||||
return Array.prototype.indexOf.call(array, item);
|
||||
}
|
||||
: function (array, item) {
|
||||
for (var i = 0, j = array.length; i < j; i++) {
|
||||
if (array[i] === item)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
arrayIndexOf: function (array, item) {
|
||||
return Array.prototype.indexOf.call(array, item);
|
||||
},
|
||||
|
||||
arrayFirst: function (array, predicate, predicateOwner) {
|
||||
for (var i = 0, j = array.length; i < j; i++) {
|
||||
|
|
@ -137,34 +65,8 @@ ko.utils = (function () {
|
|||
}
|
||||
},
|
||||
|
||||
arrayGetDistinctValues: function (array) {
|
||||
var result = [];
|
||||
if (array) {
|
||||
ko.utils.arrayForEach(array, function(item) {
|
||||
if (ko.utils.arrayIndexOf(result, item) < 0)
|
||||
result.push(item);
|
||||
});
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
arrayMap: function (array, mapping, mappingOwner) {
|
||||
var result = [];
|
||||
if (array) {
|
||||
for (var i = 0, j = array.length; i < j; i++)
|
||||
result.push(mapping.call(mappingOwner, array[i], i));
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
arrayFilter: function (array, predicate, predicateOwner) {
|
||||
var result = [];
|
||||
if (array) {
|
||||
for (var i = 0, j = array.length; i < j; i++)
|
||||
if (predicate.call(predicateOwner, array[i], i))
|
||||
result.push(array[i]);
|
||||
}
|
||||
return result;
|
||||
return array ? Array.prototype.filter.call(array, predicate, predicateOwner) : [];
|
||||
},
|
||||
|
||||
arrayPushAll: function (array, valuesToPush) {
|
||||
|
|
@ -176,17 +78,6 @@ ko.utils = (function () {
|
|||
return array;
|
||||
},
|
||||
|
||||
addOrRemoveItem: function(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);
|
||||
}
|
||||
},
|
||||
|
||||
canSetPrototype: canSetPrototype,
|
||||
|
||||
extend: extend,
|
||||
|
|
@ -201,11 +92,9 @@ ko.utils = (function () {
|
|||
if (!source)
|
||||
return source;
|
||||
var target = {};
|
||||
for (var prop in source) {
|
||||
if (hasOwnProperty.call(source, prop)) {
|
||||
target[prop] = mapping.call(mappingOwner, source[prop], prop, source);
|
||||
}
|
||||
}
|
||||
Object.entries(source).forEach(function(prop) {
|
||||
target[prop[0]] = mapping.call(mappingOwner, prop[1], prop[0], source);
|
||||
});
|
||||
return target;
|
||||
},
|
||||
|
||||
|
|
@ -245,13 +134,15 @@ ko.utils = (function () {
|
|||
},
|
||||
|
||||
replaceDomNodes: function (nodeToReplaceOrNodeArray, newNodesArray) {
|
||||
var nodesToReplaceArray = nodeToReplaceOrNodeArray.nodeType ? [nodeToReplaceOrNodeArray] : nodeToReplaceOrNodeArray;
|
||||
var nodesToReplaceArray = nodeToReplaceOrNodeArray.nodeType
|
||||
? [nodeToReplaceOrNodeArray] : nodeToReplaceOrNodeArray;
|
||||
if (nodesToReplaceArray.length > 0) {
|
||||
var insertionPoint = nodesToReplaceArray[0];
|
||||
var parent = insertionPoint.parentNode;
|
||||
for (var i = 0, j = newNodesArray.length; i < j; i++)
|
||||
var insertionPoint = nodesToReplaceArray[0],
|
||||
parent = insertionPoint.parentNode,
|
||||
i, j;
|
||||
for (i = 0, j = newNodesArray.length; i < j; i++)
|
||||
parent.insertBefore(newNodesArray[i], insertionPoint);
|
||||
for (var i = 0, j = nodesToReplaceArray.length; i < j; i++) {
|
||||
for (i = 0, j = nodesToReplaceArray.length; i < j; i++) {
|
||||
ko.removeNode(nodesToReplaceArray[i]);
|
||||
}
|
||||
}
|
||||
|
|
@ -283,7 +174,8 @@ ko.utils = (function () {
|
|||
continuousNodeArray.splice(0, 1);
|
||||
|
||||
// Rule [B]
|
||||
while (continuousNodeArray.length > 1 && continuousNodeArray[continuousNodeArray.length - 1].parentNode !== parentNode)
|
||||
while (continuousNodeArray.length > 1
|
||||
&& continuousNodeArray[continuousNodeArray.length - 1].parentNode !== parentNode)
|
||||
continuousNodeArray.length--;
|
||||
|
||||
// Rule [C]
|
||||
|
|
@ -301,14 +193,6 @@ ko.utils = (function () {
|
|||
return continuousNodeArray;
|
||||
},
|
||||
|
||||
setOptionNodeSelectionState: function (optionNode, isSelected) {
|
||||
// IE6 sometimes throws "unknown error" if you try to write to .selected directly, whereas Firefox struggles with setAttribute. Pick one based on browser.
|
||||
if (ieVersion < 7)
|
||||
optionNode.setAttribute("selected", isSelected);
|
||||
else
|
||||
optionNode.selected = isSelected;
|
||||
},
|
||||
|
||||
stringTrim: function (string) {
|
||||
return string === null || string === undefined ? '' :
|
||||
string.trim ?
|
||||
|
|
@ -324,18 +208,7 @@ ko.utils = (function () {
|
|||
},
|
||||
|
||||
domNodeIsContainedBy: function (node, containedByNode) {
|
||||
if (node === containedByNode)
|
||||
return true;
|
||||
if (node.nodeType === 11)
|
||||
return false; // Fixes issue #1162 - can't use node.contains for document fragments on IE8
|
||||
if (containedByNode.contains)
|
||||
return containedByNode.contains(node.nodeType !== 1 ? node.parentNode : node);
|
||||
if (containedByNode.compareDocumentPosition)
|
||||
return (containedByNode.compareDocumentPosition(node) & 16) == 16;
|
||||
while (node && node != containedByNode) {
|
||||
node = node.parentNode;
|
||||
}
|
||||
return !!node;
|
||||
return containedByNode.contains(node.nodeType !== 1 ? node.parentNode : node);
|
||||
},
|
||||
|
||||
domNodeIsAttachedToDocument: function (node) {
|
||||
|
|
@ -378,26 +251,10 @@ ko.utils = (function () {
|
|||
registerEventHandler: function (element, eventType, handler) {
|
||||
var wrappedHandler = ko.utils.catchFunctionErrors(handler);
|
||||
|
||||
var mustUseAttachEvent = eventsThatMustBeRegisteredUsingAttachEvent[eventType];
|
||||
if (!ko.options['useOnlyNativeEvents'] && !mustUseAttachEvent && jQueryInstance) {
|
||||
if (!jQueryEventAttachName) {
|
||||
jQueryEventAttachName = (typeof jQueryInstance(element)['on'] == 'function') ? 'on' : 'bind';
|
||||
}
|
||||
jQueryInstance(element)[jQueryEventAttachName](eventType, wrappedHandler);
|
||||
} else if (!mustUseAttachEvent && typeof element.addEventListener == "function")
|
||||
element.addEventListener(eventType, wrappedHandler, false);
|
||||
else if (typeof element.attachEvent != "undefined") {
|
||||
var attachEventHandler = function (event) { wrappedHandler.call(element, event); },
|
||||
attachEventName = "on" + eventType;
|
||||
element.attachEvent(attachEventName, attachEventHandler);
|
||||
|
||||
// IE does not dispose attachEvent handlers automatically (unlike with addEventListener)
|
||||
// so to avoid leaks, we have to remove them manually. See bug #856
|
||||
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
|
||||
element.detachEvent(attachEventName, attachEventHandler);
|
||||
});
|
||||
if (!ko.options['useOnlyNativeEvents'] && jQuery) {
|
||||
jQuery(element)['on'](eventType, wrappedHandler);
|
||||
} else
|
||||
throw new Error("Browser doesn't support addEventListener or attachEvent");
|
||||
element.addEventListener(eventType, wrappedHandler, false);
|
||||
},
|
||||
|
||||
triggerEvent: function (element, eventType) {
|
||||
|
|
@ -410,23 +267,13 @@ ko.utils = (function () {
|
|||
// In both cases, we'll use the click method instead.
|
||||
var useClickWorkaround = isClickOnCheckableElement(element, eventType);
|
||||
|
||||
if (!ko.options['useOnlyNativeEvents'] && jQueryInstance && !useClickWorkaround) {
|
||||
jQueryInstance(element)['trigger'](eventType);
|
||||
} else if (typeof document.createEvent == "function") {
|
||||
if (typeof element.dispatchEvent == "function") {
|
||||
var eventCategory = knownEventTypesByEventName[eventType] || "HTMLEvents";
|
||||
var event = document.createEvent(eventCategory);
|
||||
event.initEvent(eventType, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, element);
|
||||
element.dispatchEvent(event);
|
||||
}
|
||||
else
|
||||
throw new Error("The supplied element doesn't support dispatchEvent");
|
||||
} else if (useClickWorkaround && element.click) {
|
||||
element.click();
|
||||
} else if (typeof element.fireEvent != "undefined") {
|
||||
element.fireEvent("on" + eventType);
|
||||
if (!ko.options['useOnlyNativeEvents'] && jQuery && !useClickWorkaround) {
|
||||
jQuery(element)['trigger'](eventType);
|
||||
} else {
|
||||
throw new Error("Browser doesn't support triggering events");
|
||||
var eventCategory = knownEventTypesByEventName[eventType] || "HTMLEvents";
|
||||
var event = document.createEvent(eventCategory);
|
||||
event.initEvent(eventType, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, element);
|
||||
element.dispatchEvent(event);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -438,8 +285,6 @@ ko.utils = (function () {
|
|||
return ko.isObservable(value) ? value.peek() : value;
|
||||
},
|
||||
|
||||
toggleDomNodeCssClass: toggleDomNodeCssClass,
|
||||
|
||||
setTextContent: function(element, textContent) {
|
||||
var value = ko.utils.unwrapObservable(textContent);
|
||||
if ((value === null) || (value === undefined))
|
||||
|
|
@ -454,142 +299,10 @@ ko.utils = (function () {
|
|||
} else {
|
||||
innerTextNode.data = value;
|
||||
}
|
||||
|
||||
ko.utils.forceRefresh(element);
|
||||
},
|
||||
|
||||
setElementName: function(element, name) {
|
||||
element.name = name;
|
||||
|
||||
// Workaround IE 6/7 issue
|
||||
// - https://github.com/SteveSanderson/knockout/issues/197
|
||||
// - http://www.matts411.com/post/setting_the_name_attribute_in_ie_dom/
|
||||
if (ieVersion <= 7) {
|
||||
try {
|
||||
var escapedName = element.name.replace(/[&<>'"]/g, function(r){ return "&#" + r.charCodeAt(0) + ";"; });
|
||||
element.mergeAttributes(document.createElement("<input name='" + escapedName + "'/>"), false);
|
||||
}
|
||||
catch(e) {} // For IE9 with doc mode "IE9 Standards" and browser mode "IE9 Compatibility View"
|
||||
}
|
||||
},
|
||||
|
||||
forceRefresh: function(node) {
|
||||
// Workaround for an IE9 rendering bug - https://github.com/SteveSanderson/knockout/issues/209
|
||||
if (ieVersion >= 9) {
|
||||
// For text nodes and comment nodes (most likely virtual elements), we will have to refresh the container
|
||||
var elem = node.nodeType == 1 ? node : node.parentNode;
|
||||
if (elem.style)
|
||||
elem.style.zoom = elem.style.zoom;
|
||||
}
|
||||
},
|
||||
|
||||
ensureSelectElementIsRenderedCorrectly: function(selectElement) {
|
||||
// Workaround for IE9 rendering bug - it doesn't reliably display all the text in dynamically-added select boxes unless you force it to re-render by updating the width.
|
||||
// (See https://github.com/SteveSanderson/knockout/issues/312, http://stackoverflow.com/questions/5908494/select-only-shows-first-char-of-selected-option)
|
||||
// Also fixes IE7 and IE8 bug that causes selects to be zero width if enclosed by 'if' or 'with'. (See issue #839)
|
||||
if (ieVersion) {
|
||||
var originalWidth = selectElement.style.width;
|
||||
selectElement.style.width = 0;
|
||||
selectElement.style.width = originalWidth;
|
||||
}
|
||||
},
|
||||
|
||||
range: function (min, max) {
|
||||
min = ko.utils.unwrapObservable(min);
|
||||
max = ko.utils.unwrapObservable(max);
|
||||
var result = [];
|
||||
for (var i = min; i <= max; i++)
|
||||
result.push(i);
|
||||
return result;
|
||||
},
|
||||
|
||||
makeArray: function(arrayLikeObject) {
|
||||
var result = [];
|
||||
for (var i = 0, j = arrayLikeObject.length; i < j; i++) {
|
||||
result.push(arrayLikeObject[i]);
|
||||
};
|
||||
return result;
|
||||
},
|
||||
|
||||
createSymbolOrString: function(identifier) {
|
||||
return canUseSymbols ? Symbol(identifier) : identifier;
|
||||
},
|
||||
|
||||
isIe6 : isIe6,
|
||||
isIe7 : isIe7,
|
||||
ieVersion : ieVersion,
|
||||
|
||||
getFormFields: function(form, fieldName) {
|
||||
var fields = ko.utils.makeArray(form.getElementsByTagName("input")).concat(ko.utils.makeArray(form.getElementsByTagName("textarea")));
|
||||
var isMatchingField = (typeof fieldName == 'string')
|
||||
? function(field) { return field.name === fieldName }
|
||||
: function(field) { return fieldName.test(field.name) }; // Treat fieldName as regex or object containing predicate
|
||||
var matches = [];
|
||||
for (var i = fields.length - 1; i >= 0; i--) {
|
||||
if (isMatchingField(fields[i]))
|
||||
matches.push(fields[i]);
|
||||
};
|
||||
return matches;
|
||||
},
|
||||
|
||||
parseJson: function (jsonString) {
|
||||
if (typeof jsonString == "string") {
|
||||
jsonString = ko.utils.stringTrim(jsonString);
|
||||
if (jsonString) {
|
||||
if (JSON && JSON.parse) // Use native parsing where available
|
||||
return JSON.parse(jsonString);
|
||||
return (new Function("return " + jsonString))(); // Fallback on less safe parsing for older browsers
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
stringifyJson: function (data, replacer, space) { // replacer and space are optional
|
||||
if (!JSON || !JSON.stringify)
|
||||
throw new Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js");
|
||||
return JSON.stringify(ko.utils.unwrapObservable(data), replacer, space);
|
||||
},
|
||||
|
||||
postJson: function (urlOrForm, data, options) {
|
||||
options = options || {};
|
||||
var params = options['params'] || {};
|
||||
var includeFields = options['includeFields'] || this.fieldsIncludedWithJsonPost;
|
||||
var url = urlOrForm;
|
||||
|
||||
// If we were given a form, use its 'action' URL and pick out any requested field values
|
||||
if((typeof urlOrForm == 'object') && (ko.utils.tagNameLower(urlOrForm) === "form")) {
|
||||
var originalForm = urlOrForm;
|
||||
url = originalForm.action;
|
||||
for (var i = includeFields.length - 1; i >= 0; i--) {
|
||||
var fields = ko.utils.getFormFields(originalForm, includeFields[i]);
|
||||
for (var j = fields.length - 1; j >= 0; j--)
|
||||
params[fields[j].name] = fields[j].value;
|
||||
}
|
||||
}
|
||||
|
||||
data = ko.utils.unwrapObservable(data);
|
||||
var form = document.createElement("form");
|
||||
form.style.display = "none";
|
||||
form.action = url;
|
||||
form.method = "post";
|
||||
for (var key in data) {
|
||||
// Since 'data' this is a model object, we include all properties including those inherited from its prototype
|
||||
var input = document.createElement("input");
|
||||
input.type = "hidden";
|
||||
input.name = key;
|
||||
input.value = ko.utils.stringifyJson(ko.utils.unwrapObservable(data[key]));
|
||||
form.appendChild(input);
|
||||
}
|
||||
objectForEach(params, function(key, value) {
|
||||
var input = document.createElement("input");
|
||||
input.type = "hidden";
|
||||
input.name = key;
|
||||
input.value = value;
|
||||
form.appendChild(input);
|
||||
});
|
||||
document.body.appendChild(form);
|
||||
options['submitter'] ? options['submitter'](form) : form.submit();
|
||||
setTimeout(function () { form.parentNode.removeChild(form); }, 0);
|
||||
return Array['from'](arrayLikeObject);
|
||||
}
|
||||
}
|
||||
}());
|
||||
|
|
@ -598,47 +311,17 @@ ko.exportSymbol('utils', ko.utils);
|
|||
ko.exportSymbol('utils.arrayForEach', ko.utils.arrayForEach);
|
||||
ko.exportSymbol('utils.arrayFirst', ko.utils.arrayFirst);
|
||||
ko.exportSymbol('utils.arrayFilter', ko.utils.arrayFilter);
|
||||
ko.exportSymbol('utils.arrayGetDistinctValues', ko.utils.arrayGetDistinctValues);
|
||||
ko.exportSymbol('utils.arrayIndexOf', ko.utils.arrayIndexOf);
|
||||
ko.exportSymbol('utils.arrayMap', ko.utils.arrayMap);
|
||||
ko.exportSymbol('utils.arrayPushAll', ko.utils.arrayPushAll);
|
||||
ko.exportSymbol('utils.arrayRemoveItem', ko.utils.arrayRemoveItem);
|
||||
ko.exportSymbol('utils.cloneNodes', ko.utils.cloneNodes);
|
||||
ko.exportSymbol('utils.createSymbolOrString', ko.utils.createSymbolOrString);
|
||||
ko.exportSymbol('utils.extend', ko.utils.extend);
|
||||
ko.exportSymbol('utils.fieldsIncludedWithJsonPost', ko.utils.fieldsIncludedWithJsonPost);
|
||||
ko.exportSymbol('utils.getFormFields', ko.utils.getFormFields);
|
||||
ko.exportSymbol('utils.objectMap', ko.utils.objectMap);
|
||||
ko.exportSymbol('utils.peekObservable', ko.utils.peekObservable);
|
||||
ko.exportSymbol('utils.postJson', ko.utils.postJson);
|
||||
ko.exportSymbol('utils.parseJson', ko.utils.parseJson);
|
||||
ko.exportSymbol('utils.registerEventHandler', ko.utils.registerEventHandler);
|
||||
ko.exportSymbol('utils.stringifyJson', ko.utils.stringifyJson);
|
||||
ko.exportSymbol('utils.range', ko.utils.range);
|
||||
ko.exportSymbol('utils.toggleDomNodeCssClass', ko.utils.toggleDomNodeCssClass);
|
||||
ko.exportSymbol('utils.triggerEvent', ko.utils.triggerEvent);
|
||||
ko.exportSymbol('utils.unwrapObservable', ko.utils.unwrapObservable);
|
||||
ko.exportSymbol('utils.objectForEach', ko.utils.objectForEach);
|
||||
ko.exportSymbol('utils.addOrRemoveItem', ko.utils.addOrRemoveItem);
|
||||
ko.exportSymbol('utils.setTextContent', ko.utils.setTextContent);
|
||||
ko.exportSymbol('unwrap', ko.utils.unwrapObservable); // Convenient shorthand, because this is used so commonly
|
||||
|
||||
if (!Function.prototype['bind']) {
|
||||
// Function.prototype.bind is a standard part of ECMAScript 5th Edition (December 2009, http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf)
|
||||
// In case the browser doesn't implement it natively, provide a JavaScript implementation. This implementation is based on the one in prototype.js
|
||||
Function.prototype['bind'] = function (object) {
|
||||
var originalFunction = this;
|
||||
if (arguments.length === 1) {
|
||||
return function () {
|
||||
return originalFunction.apply(object, arguments);
|
||||
};
|
||||
} else {
|
||||
var partialArgs = Array.prototype.slice.call(arguments, 1);
|
||||
return function () {
|
||||
var args = partialArgs.slice(0);
|
||||
args.push.apply(args, arguments);
|
||||
return originalFunction.apply(object, args);
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue