You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
655 lines
37 KiB
655 lines
37 KiB
ko.bindingHandlers.truncatedText = {
|
|
update: function(element, valueAccessor, allBindingsAccessor) {
|
|
var value = ko.utils.unwrapObservable(valueAccessor());
|
|
if (!value) return
|
|
var length = ko.utils.unwrapObservable(allBindingsAccessor().length) || ko.bindingHandlers.truncatedText.defaultLength,
|
|
truncatedValue = value.length > length ? convertHTMLtoText(value.substring(0, Math.min(value.length, length))) + "…" : convertHTMLtoText(value);
|
|
ko.bindingHandlers.html.update(element, function() {
|
|
return truncatedValue;
|
|
});
|
|
},
|
|
defaultLength: 15
|
|
};
|
|
ko.bindingHandlers.truncatedTextCenter = {
|
|
update: function(element, valueAccessor, allBindingsAccessor) {
|
|
var value = ko.utils.unwrapObservable(valueAccessor())
|
|
if (!value) return
|
|
var maxLength = 60;
|
|
if(value.length > maxLength) {
|
|
var charsToShow = maxLength - 3,
|
|
frontChars = Math.ceil(charsToShow/2),
|
|
backChars = Math.floor(charsToShow/2);
|
|
var truncatedValue = convertHTMLtoText(value.substr(0, frontChars)) + '…' + convertHTMLtoText(value.substr(value.length - backChars));
|
|
} else {
|
|
var truncatedValue = convertHTMLtoText(value);
|
|
}
|
|
ko.bindingHandlers.html.update(element, function() {
|
|
return truncatedValue;
|
|
});
|
|
}
|
|
};
|
|
ko.bindingHandlers.longText = {
|
|
update: function(element, valueAccessor, allBindingsAccessor) {
|
|
// Input is an array
|
|
var value = ko.utils.unwrapObservable(valueAccessor())
|
|
|
|
// Convert HTML entities for all but the Script (because of the (more)-link)
|
|
if(allBindingsAccessor.get('longTextType') != "Script") {
|
|
value = value.map(convertHTMLtoText)
|
|
}
|
|
|
|
// Any <br>'s?
|
|
var outputText = '';
|
|
if(value.length > 4) {
|
|
// Inital 3, then the button, then the closing
|
|
outputText += value.shift() + '<br />' + value.shift() + '<br />' + value.shift() + ' ';
|
|
outputText += '<a href="#" class="history-status-more">(' + glitterTranslate.moreText + ')</a><br />';
|
|
outputText += '<span class="history-status-hidden">';
|
|
outputText += value.join('<br />');
|
|
outputText += '</span>';
|
|
} else {
|
|
// Nothing special
|
|
outputText += value.join('<br />');
|
|
}
|
|
|
|
// Replace link to our website
|
|
outputText = outputText.replace('https://sabnzbd.org/not-complete', '<a href="https://sabnzbd.org/not-complete" class="history-status-dmca" target="_blank">https://sabnzbd.org/not-complete</a>')
|
|
|
|
ko.bindingHandlers.html.update(element, function() {
|
|
return outputText;
|
|
});
|
|
}
|
|
};
|
|
// Adapted for SABnzbd usage
|
|
ko.bindingHandlers.filedrop = {
|
|
init: function(element, valueAccessor) {
|
|
var options = $.extend({}, {
|
|
overlaySelector: null
|
|
}, valueAccessor());
|
|
if(!options.onFileDrop)
|
|
return;
|
|
else if(!window.File || !window.FileReader || !window.FileList || !window.FormData) {
|
|
console.log("File drop disabled because this browser is too old");
|
|
return;
|
|
}
|
|
// EDITED to prevent drag-and-drop from inside own screen
|
|
$(element).bind("dragstart", function(e) {
|
|
$(element).data('internal-drag', true)
|
|
// Remove after timeout
|
|
setTimeout(function() {
|
|
$(element).data('internal-drag', false)
|
|
}, 2000)
|
|
});
|
|
$(element).bind("dragenter", function(e) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
// Was it external or internal?
|
|
if($(element).data('internal-drag'))
|
|
return;
|
|
if(options.overlaySelector)
|
|
$(options.overlaySelector).show();
|
|
});
|
|
$(element).bind("dragleave", function(e) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
// EDITED FOR FIREFOX!
|
|
// Without the check for is(), the screen will blink in firefox!
|
|
if(options.overlaySelector && $(e.target).is('.main-filedrop'))
|
|
$(options.overlaySelector).hide();
|
|
});
|
|
$(element).bind("drop", function(e) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
if(options.overlaySelector)
|
|
$(options.overlaySelector).hide();
|
|
if(typeof options.onFileDrop === "function") {
|
|
options.onFileDrop(e.originalEvent.dataTransfer.files)
|
|
}
|
|
});
|
|
}
|
|
};
|
|
$(document).bind('dragover', function(e) {
|
|
e.preventDefault();
|
|
});
|
|
|
|
/*! Knockout Persist - v0.1.0 - 2015-12-28
|
|
* https://github.com/spoike/knockout.persist
|
|
* Copyright (c) 2013 Mikael Brassman; Licensed MIT
|
|
* Safihre edited to better detect if localStorage is possible */
|
|
(function(ko) {
|
|
// Don't crash on browsers that are missing localStorage
|
|
try {
|
|
localStorage.setItem('test', 'test');
|
|
localStorage.removeItem('test');
|
|
} catch(e) {
|
|
return false;
|
|
}
|
|
|
|
ko.extenders.persist = function(target, key) {
|
|
var initialValue = target();
|
|
// Load existing value from localStorage if set
|
|
if (key && localStorage.getItem(key) !== null) {
|
|
try {
|
|
initialValue = JSON.parse(localStorage.getItem(key));
|
|
} catch (e) {
|
|
}
|
|
}
|
|
target(initialValue);
|
|
// Subscribe to new values and add them to localStorage
|
|
target.subscribe(function (newValue) {
|
|
localStorage.setItem(key, ko.toJSON(newValue));
|
|
});
|
|
return target;
|
|
};
|
|
})(ko);
|
|
|
|
// knockout-sortable 1.2.0 | (c) 2019 Ryan Niemeyer | http://www.opensource.org/licenses/mit-license
|
|
;(function(factory) {
|
|
if (typeof define === "function" && define.amd) {
|
|
// AMD anonymous module
|
|
define(["knockout", "jquery", "jquery-ui/ui/widgets/sortable", "jquery-ui/ui/widgets/draggable"], factory);
|
|
} else if (typeof require === "function" && typeof exports === "object" && typeof module === "object") {
|
|
// CommonJS module
|
|
var ko = require("knockout"),
|
|
jQuery = require("jquery");
|
|
require("jquery-ui/ui/widgets/sortable");
|
|
require("jquery-ui/ui/widgets/draggable");
|
|
factory(ko, jQuery);
|
|
} else {
|
|
// No module loader (plain <script> tag) - put directly in global namespace
|
|
factory(window.ko, window.jQuery);
|
|
}
|
|
})(function(ko, $) {
|
|
var ITEMKEY = "ko_sortItem",
|
|
INDEXKEY = "ko_sourceIndex",
|
|
LISTKEY = "ko_sortList",
|
|
PARENTKEY = "ko_parentList",
|
|
DRAGKEY = "ko_dragItem",
|
|
unwrap = ko.utils.unwrapObservable,
|
|
dataGet = ko.utils.domData.get,
|
|
dataSet = ko.utils.domData.set,
|
|
version = $.ui && $.ui.version,
|
|
//1.8.24 included a fix for how events were triggered in nested sortables. indexOf checks will fail if version starts with that value (0 vs. -1)
|
|
hasNestedSortableFix = version && version.indexOf("1.6.") && version.indexOf("1.7.") && (version.indexOf("1.8.") || version === "1.8.24");
|
|
|
|
//internal afterRender that adds meta-data to children
|
|
var addMetaDataAfterRender = function(elements, data) {
|
|
ko.utils.arrayForEach(elements, function(element) {
|
|
if (element.nodeType === 1) {
|
|
dataSet(element, ITEMKEY, data);
|
|
dataSet(element, PARENTKEY, dataGet(element.parentNode, LISTKEY));
|
|
}
|
|
});
|
|
};
|
|
|
|
//prepare the proper options for the template binding
|
|
var prepareTemplateOptions = function(valueAccessor, dataName) {
|
|
var result = {},
|
|
options = {},
|
|
actualAfterRender;
|
|
|
|
//build our options to pass to the template engine
|
|
if (ko.utils.peekObservable(valueAccessor()).data) {
|
|
options = unwrap(valueAccessor() || {});
|
|
result[dataName] = options.data;
|
|
if (options.hasOwnProperty("template")) {
|
|
result.name = options.template;
|
|
}
|
|
} else {
|
|
result[dataName] = valueAccessor();
|
|
}
|
|
|
|
ko.utils.arrayForEach(["afterAdd", "afterRender", "as", "beforeRemove", "includeDestroyed", "templateEngine", "templateOptions", "nodes"], function (option) {
|
|
if (options.hasOwnProperty(option)) {
|
|
result[option] = options[option];
|
|
} else if (ko.bindingHandlers.sortable.hasOwnProperty(option)) {
|
|
result[option] = ko.bindingHandlers.sortable[option];
|
|
}
|
|
});
|
|
|
|
//use an afterRender function to add meta-data
|
|
if (dataName === "foreach") {
|
|
if (result.afterRender) {
|
|
//wrap the existing function, if it was passed
|
|
actualAfterRender = result.afterRender;
|
|
result.afterRender = function(element, data) {
|
|
addMetaDataAfterRender.call(data, element, data);
|
|
actualAfterRender.call(data, element, data);
|
|
};
|
|
} else {
|
|
result.afterRender = addMetaDataAfterRender;
|
|
}
|
|
}
|
|
|
|
//return options to pass to the template binding
|
|
return result;
|
|
};
|
|
|
|
var updateIndexFromDestroyedItems = function(index, items) {
|
|
var unwrapped = unwrap(items);
|
|
|
|
if (unwrapped) {
|
|
for (var i = 0; i <= index; i++) {
|
|
//add one for every destroyed item we find before the targetIndex in the target array
|
|
if (unwrapped[i] && unwrap(unwrapped[i]._destroy)) {
|
|
index++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return index;
|
|
};
|
|
|
|
//remove problematic leading/trailing whitespace from templates
|
|
var stripTemplateWhitespace = function(element, name) {
|
|
var templateSource,
|
|
templateElement;
|
|
|
|
//process named templates
|
|
if (name) {
|
|
templateElement = document.getElementById(name);
|
|
if (templateElement) {
|
|
templateSource = new ko.templateSources.domElement(templateElement);
|
|
templateSource.text($.trim(templateSource.text()));
|
|
}
|
|
}
|
|
else {
|
|
//remove leading/trailing non-elements from anonymous templates
|
|
$(element).contents().each(function() {
|
|
if (this && this.nodeType !== 1) {
|
|
element.removeChild(this);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
//connect items with observableArrays
|
|
ko.bindingHandlers.sortable = {
|
|
init: function(element, valueAccessor, allBindingsAccessor, data, context) {
|
|
var $element = $(element),
|
|
value = unwrap(valueAccessor()) || {},
|
|
templateOptions = prepareTemplateOptions(valueAccessor, "foreach"),
|
|
sortable = {},
|
|
startActual, updateActual;
|
|
|
|
stripTemplateWhitespace(element, templateOptions.name);
|
|
|
|
//build a new object that has the global options with overrides from the binding
|
|
$.extend(true, sortable, ko.bindingHandlers.sortable);
|
|
if (value.options && sortable.options) {
|
|
ko.utils.extend(sortable.options, value.options);
|
|
delete value.options;
|
|
}
|
|
ko.utils.extend(sortable, value);
|
|
|
|
//if allowDrop is an observable or a function, then execute it in a computed observable
|
|
if (sortable.connectClass && (ko.isObservable(sortable.allowDrop) || typeof sortable.allowDrop == "function")) {
|
|
ko.computed({
|
|
read: function() {
|
|
var value = unwrap(sortable.allowDrop),
|
|
shouldAdd = typeof value == "function" ? value.call(this, templateOptions.foreach) : value;
|
|
ko.utils.toggleDomNodeCssClass(element, sortable.connectClass, shouldAdd);
|
|
},
|
|
disposeWhenNodeIsRemoved: element
|
|
}, this);
|
|
} else {
|
|
ko.utils.toggleDomNodeCssClass(element, sortable.connectClass, sortable.allowDrop);
|
|
}
|
|
|
|
//wrap the template binding
|
|
ko.bindingHandlers.template.init(element, function() { return templateOptions; }, allBindingsAccessor, data, context);
|
|
|
|
//keep a reference to start/update functions that might have been passed in
|
|
startActual = sortable.options.start;
|
|
updateActual = sortable.options.update;
|
|
|
|
//ensure draggable table row cells maintain their width while dragging (unless a helper is provided)
|
|
if ( !sortable.options.helper ) {
|
|
sortable.options.helper = function(e, ui) {
|
|
if (ui.is("tr")) {
|
|
ui.children().each(function() {
|
|
$(this).width($(this).width());
|
|
});
|
|
}
|
|
return ui;
|
|
};
|
|
}
|
|
|
|
//initialize sortable binding after template binding has rendered in update function
|
|
var createTimeout = setTimeout(function() {
|
|
var dragItem;
|
|
var originalReceive = sortable.options.receive;
|
|
|
|
$element.sortable(ko.utils.extend(sortable.options, {
|
|
start: function(event, ui) {
|
|
//track original index
|
|
var el = ui.item[0];
|
|
dataSet(el, INDEXKEY, ko.utils.arrayIndexOf(ui.item.parent().children(), el));
|
|
|
|
// SABnzbd-edit: Add class to parent for active sorting
|
|
$(el).parent().parent().addClass('table-active-sorting')
|
|
|
|
//make sure that fields have a chance to update model
|
|
ui.item.find("input:focus").change();
|
|
if (startActual) {
|
|
startActual.apply(this, arguments);
|
|
}
|
|
},
|
|
receive: function(event, ui) {
|
|
//optionally apply an existing receive handler
|
|
if (typeof originalReceive === "function") {
|
|
originalReceive.call(this, event, ui);
|
|
}
|
|
|
|
dragItem = dataGet(ui.item[0], DRAGKEY);
|
|
if (dragItem) {
|
|
//copy the model item, if a clone option is provided
|
|
if (dragItem.clone) {
|
|
dragItem = dragItem.clone();
|
|
}
|
|
|
|
//configure a handler to potentially manipulate item before drop
|
|
if (sortable.dragged) {
|
|
dragItem = sortable.dragged.call(this, dragItem, event, ui) || dragItem;
|
|
}
|
|
}
|
|
},
|
|
update: function(event, ui) {
|
|
var sourceParent, targetParent, sourceIndex, targetIndex, arg,
|
|
el = ui.item[0],
|
|
parentEl = ui.item.parent()[0],
|
|
item = dataGet(el, ITEMKEY) || dragItem;
|
|
|
|
if (!item) {
|
|
$(el).remove();
|
|
}
|
|
dragItem = null;
|
|
|
|
//make sure that moves only run once, as update fires on multiple containers
|
|
if (item && (this === parentEl) || (!hasNestedSortableFix && $.contains(this, parentEl))) {
|
|
//identify parents
|
|
sourceParent = dataGet(el, PARENTKEY);
|
|
sourceIndex = dataGet(el, INDEXKEY);
|
|
targetParent = dataGet(el.parentNode, LISTKEY);
|
|
targetIndex = ko.utils.arrayIndexOf(ui.item.parent().children(), el);
|
|
|
|
//take destroyed items into consideration
|
|
if (!templateOptions.includeDestroyed) {
|
|
sourceIndex = updateIndexFromDestroyedItems(sourceIndex, sourceParent);
|
|
targetIndex = updateIndexFromDestroyedItems(targetIndex, targetParent);
|
|
}
|
|
|
|
//build up args for the callbacks
|
|
if (sortable.beforeMove || sortable.afterMove) {
|
|
arg = {
|
|
item: item,
|
|
sourceParent: sourceParent,
|
|
sourceParentNode: sourceParent && ui.sender || el.parentNode,
|
|
sourceIndex: sourceIndex,
|
|
targetParent: targetParent,
|
|
targetIndex: targetIndex,
|
|
cancelDrop: false
|
|
};
|
|
|
|
//execute the configured callback prior to actually moving items
|
|
if (sortable.beforeMove) {
|
|
sortable.beforeMove.call(this, arg, event, ui);
|
|
}
|
|
}
|
|
|
|
//call cancel on the correct list, so KO can take care of DOM manipulation
|
|
if (sourceParent) {
|
|
$(sourceParent === targetParent ? this : ui.sender || this).sortable("cancel");
|
|
}
|
|
//for a draggable item just remove the element
|
|
else {
|
|
$(el).remove();
|
|
}
|
|
|
|
//if beforeMove told us to cancel, then we are done
|
|
if (arg && arg.cancelDrop) {
|
|
return;
|
|
}
|
|
|
|
//if the strategy option is unset or false, employ the order strategy involving removal and insertion of items
|
|
if (!sortable.hasOwnProperty("strategyMove") || sortable.strategyMove === false) {
|
|
//do the actual move
|
|
if (targetIndex >= 0) {
|
|
if (sourceParent) {
|
|
sourceParent.splice(sourceIndex, 1);
|
|
|
|
//if using deferred updates plugin, force updates
|
|
if (ko.processAllDeferredBindingUpdates) {
|
|
ko.processAllDeferredBindingUpdates();
|
|
}
|
|
|
|
//if using deferred updates on knockout 3.4, force updates
|
|
if (ko.options && ko.options.deferUpdates) {
|
|
ko.tasks.runEarly();
|
|
}
|
|
}
|
|
|
|
targetParent.splice(targetIndex, 0, item);
|
|
}
|
|
|
|
//rendering is handled by manipulating the observableArray; ignore dropped element
|
|
dataSet(el, ITEMKEY, null);
|
|
}
|
|
else { //employ the strategy of moving items
|
|
if (targetIndex >= 0) {
|
|
if (sourceParent) {
|
|
if (sourceParent !== targetParent) {
|
|
// moving from one list to another
|
|
|
|
sourceParent.splice(sourceIndex, 1);
|
|
targetParent.splice(targetIndex, 0, item);
|
|
|
|
//rendering is handled by manipulating the observableArray; ignore dropped element
|
|
dataSet(el, ITEMKEY, null);
|
|
ui.item.remove();
|
|
}
|
|
else {
|
|
// moving within same list
|
|
var underlyingList = unwrap(sourceParent);
|
|
|
|
// notify 'beforeChange' subscribers
|
|
if (sourceParent.valueWillMutate) {
|
|
sourceParent.valueWillMutate();
|
|
}
|
|
|
|
// move from source index ...
|
|
underlyingList.splice(sourceIndex, 1);
|
|
// ... to target index
|
|
underlyingList.splice(targetIndex, 0, item);
|
|
|
|
// notify subscribers
|
|
if (sourceParent.valueHasMutated) {
|
|
sourceParent.valueHasMutated();
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// drop new element from outside
|
|
targetParent.splice(targetIndex, 0, item);
|
|
|
|
//rendering is handled by manipulating the observableArray; ignore dropped element
|
|
dataSet(el, ITEMKEY, null);
|
|
ui.item.remove();
|
|
}
|
|
}
|
|
}
|
|
|
|
//if using deferred updates plugin, force updates
|
|
if (ko.processAllDeferredBindingUpdates) {
|
|
ko.processAllDeferredBindingUpdates();
|
|
}
|
|
|
|
//allow binding to accept a function to execute after moving the item
|
|
if (sortable.afterMove) {
|
|
sortable.afterMove.call(this, arg, event, ui);
|
|
}
|
|
}
|
|
|
|
if (updateActual) {
|
|
updateActual.apply(this, arguments);
|
|
}
|
|
},
|
|
connectWith: sortable.connectClass ? "." + sortable.connectClass : false,
|
|
// SABnzbd-edit: we need placeholder
|
|
placeholder: 'sortable-placeholder'
|
|
}));
|
|
|
|
//handle enabling/disabling sorting
|
|
if (sortable.isEnabled !== undefined) {
|
|
ko.computed({
|
|
read: function() {
|
|
$element.sortable(unwrap(sortable.isEnabled) ? "enable" : "disable");
|
|
},
|
|
disposeWhenNodeIsRemoved: element
|
|
});
|
|
}
|
|
}, 0);
|
|
|
|
//handle disposal
|
|
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
|
|
//only call destroy if sortable has been created
|
|
if ($element.data("ui-sortable") || $element.data("sortable")) {
|
|
$element.sortable("destroy");
|
|
}
|
|
|
|
ko.utils.toggleDomNodeCssClass(element, sortable.connectClass, false);
|
|
|
|
//do not create the sortable if the element has been removed from DOM
|
|
clearTimeout(createTimeout);
|
|
});
|
|
|
|
return { 'controlsDescendantBindings': true };
|
|
},
|
|
update: function(element, valueAccessor, allBindingsAccessor, data, context) {
|
|
var templateOptions = prepareTemplateOptions(valueAccessor, "foreach");
|
|
|
|
//attach meta-data
|
|
dataSet(element, LISTKEY, templateOptions.foreach);
|
|
|
|
//call template binding's update with correct options
|
|
ko.bindingHandlers.template.update(element, function() { return templateOptions; }, allBindingsAccessor, data, context);
|
|
},
|
|
connectClass: 'ko_container',
|
|
allowDrop: true,
|
|
afterMove: null,
|
|
beforeMove: null,
|
|
options: {
|
|
helper: function(e, tr) {
|
|
var $originals = tr.children();
|
|
var $helper = tr.clone();
|
|
$helper.children().each(function(index) {
|
|
// Set helper cell sizes to match the original sizes
|
|
$(this).width($originals.eq(index).outerWidth());
|
|
$(this).css('background-color', '#F0F0F0')
|
|
$(this).children('.row-wrap-text').width($originals.eq(index).innerWidth() - 50);
|
|
});
|
|
return $helper;
|
|
}
|
|
}
|
|
};
|
|
|
|
//create a draggable that is appropriate for dropping into a sortable
|
|
ko.bindingHandlers.draggable = {
|
|
init: function(element, valueAccessor, allBindingsAccessor, data, context) {
|
|
var value = unwrap(valueAccessor()) || {},
|
|
options = value.options || {},
|
|
draggableOptions = ko.utils.extend({}, ko.bindingHandlers.draggable.options),
|
|
templateOptions = prepareTemplateOptions(valueAccessor, "data"),
|
|
connectClass = value.connectClass || ko.bindingHandlers.draggable.connectClass,
|
|
isEnabled = value.isEnabled !== undefined ? value.isEnabled : ko.bindingHandlers.draggable.isEnabled;
|
|
|
|
value = "data" in value ? value.data : value;
|
|
|
|
//set meta-data
|
|
dataSet(element, DRAGKEY, value);
|
|
|
|
//override global options with override options passed in
|
|
ko.utils.extend(draggableOptions, options);
|
|
|
|
//setup connection to a sortable
|
|
draggableOptions.connectToSortable = connectClass ? "." + connectClass : false;
|
|
|
|
//initialize draggable
|
|
$(element).draggable(draggableOptions);
|
|
|
|
//handle enabling/disabling sorting
|
|
if (isEnabled !== undefined) {
|
|
ko.computed({
|
|
read: function() {
|
|
$(element).draggable(unwrap(isEnabled) ? "enable" : "disable");
|
|
},
|
|
disposeWhenNodeIsRemoved: element
|
|
});
|
|
}
|
|
|
|
//handle disposal
|
|
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
|
|
$(element).draggable("destroy");
|
|
});
|
|
|
|
return ko.bindingHandlers.template.init(element, function() { return templateOptions; }, allBindingsAccessor, data, context);
|
|
},
|
|
update: function(element, valueAccessor, allBindingsAccessor, data, context) {
|
|
var templateOptions = prepareTemplateOptions(valueAccessor, "data");
|
|
|
|
return ko.bindingHandlers.template.update(element, function() { return templateOptions; }, allBindingsAccessor, data, context);
|
|
},
|
|
connectClass: ko.bindingHandlers.sortable.connectClass,
|
|
options: {
|
|
helper: "clone"
|
|
}
|
|
};
|
|
});
|
|
|
|
|
|
ko.bindingHandlers.slider = {
|
|
init: function(element, valueAccessor, allBindingsAccessor) {
|
|
var options = allBindingsAccessor().sliderOptions || {};
|
|
$(element).slider(options);
|
|
/* This created many update signallings when nothing changed
|
|
ko.utils.registerEventHandler(element, "slidechange", function(event, ui) {
|
|
var observable = valueAccessor();
|
|
observable(ui.value);
|
|
});*/
|
|
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
|
|
$(element).slider("destroy");
|
|
});
|
|
ko.utils.registerEventHandler(element, "slide", function(event, ui) {
|
|
var observable = valueAccessor();
|
|
observable(ui.value);
|
|
});
|
|
},
|
|
update: function(element, valueAccessor) {
|
|
var value = ko.utils.unwrapObservable(valueAccessor());
|
|
if(isNaN(value)) value = 0;
|
|
$(element).slider("value", value);
|
|
}
|
|
};
|
|
|
|
/// Knockout Mapping plugin v2.4.1
|
|
/// (c) 2013 Steven Sanderson, Roy Jacobs - http://knockoutjs.com/
|
|
/// License: MIT (http://www.opensource.org/licenses/mit-license.php)
|
|
(function(e){"function"===typeof require&&"object"===typeof exports&&"object"===typeof module?e(require("knockout"),exports):"function"===typeof define&&define.amd?define(["knockout","exports"],e):e(ko,ko.mapping={})})(function(e,f){function y(b,c){var a,d;for(d in c)if(c.hasOwnProperty(d)&&c[d])if(a=f.getType(b[d]),d&&b[d]&&"array"!==a&&"string"!==a)y(b[d],c[d]);else if("array"===f.getType(b[d])&&"array"===f.getType(c[d])){a=b;for(var e=d,l=b[d],n=c[d],t={},g=l.length-1;0<=g;--g)t[l[g]]=l[g];for(g=
|
|
n.length-1;0<=g;--g)t[n[g]]=n[g];l=[];n=void 0;for(n in t)l.push(t[n]);a[e]=l}else b[d]=c[d]}function E(b,c){var a={};y(a,b);y(a,c);return a}function z(b,c){for(var a=E({},b),e=L.length-1;0<=e;e--){var f=L[e];a[f]&&(a[""]instanceof Object||(a[""]={}),a[""][f]=a[f],delete a[f])}c&&(a.ignore=h(c.ignore,a.ignore),a.include=h(c.include,a.include),a.copy=h(c.copy,a.copy),a.observe=h(c.observe,a.observe));a.ignore=h(a.ignore,j.ignore);a.include=h(a.include,j.include);a.copy=h(a.copy,j.copy);a.observe=h(a.observe,
|
|
j.observe);a.mappedProperties=a.mappedProperties||{};a.copiedProperties=a.copiedProperties||{};return a}function h(b,c){"array"!==f.getType(b)&&(b="undefined"===f.getType(b)?[]:[b]);"array"!==f.getType(c)&&(c="undefined"===f.getType(c)?[]:[c]);return e.utils.arrayGetDistinctValues(b.concat(c))}function F(b,c,a,d,k,l,n){var t="array"===f.getType(e.utils.unwrapObservable(c));l=l||"";if(f.isMapped(b)){var g=e.utils.unwrapObservable(b)[p];a=E(g,a)}var j=n||k,h=function(){return a[d]&&a[d].create instanceof
|
|
Function},x=function(b){var f=G,g=e.dependentObservable;e.dependentObservable=function(a,b,c){c=c||{};a&&"object"==typeof a&&(c=a);var d=c.deferEvaluation,M=!1;c.deferEvaluation=!0;a=new H(a,b,c);if(!d){var g=a,d=e.dependentObservable;e.dependentObservable=H;a=e.isWriteableObservable(g);e.dependentObservable=d;d=H({read:function(){M||(e.utils.arrayRemoveItem(f,g),M=!0);return g.apply(g,arguments)},write:a&&function(a){return g(a)},deferEvaluation:!0});d.__DO=g;a=d;f.push(a)}return a};e.dependentObservable.fn=
|
|
H.fn;e.computed=e.dependentObservable;b=e.utils.unwrapObservable(k)instanceof Array?a[d].create({data:b||c,parent:j,skip:N}):a[d].create({data:b||c,parent:j});e.dependentObservable=g;e.computed=e.dependentObservable;return b},u=function(){return a[d]&&a[d].update instanceof Function},v=function(b,f){var g={data:f||c,parent:j,target:e.utils.unwrapObservable(b)};e.isWriteableObservable(b)&&(g.observable=b);return a[d].update(g)};if(n=I.get(c))return n;d=d||"";if(t){var t=[],s=!1,m=function(a){return a};
|
|
a[d]&&a[d].key&&(m=a[d].key,s=!0);e.isObservable(b)||(b=e.observableArray([]),b.mappedRemove=function(a){var c="function"==typeof a?a:function(b){return b===m(a)};return b.remove(function(a){return c(m(a))})},b.mappedRemoveAll=function(a){var c=C(a,m);return b.remove(function(a){return-1!=e.utils.arrayIndexOf(c,m(a))})},b.mappedDestroy=function(a){var c="function"==typeof a?a:function(b){return b===m(a)};return b.destroy(function(a){return c(m(a))})},b.mappedDestroyAll=function(a){var c=C(a,m);return b.destroy(function(a){return-1!=
|
|
e.utils.arrayIndexOf(c,m(a))})},b.mappedIndexOf=function(a){var c=C(b(),m);a=m(a);return e.utils.arrayIndexOf(c,a)},b.mappedGet=function(a){return b()[b.mappedIndexOf(a)]},b.mappedCreate=function(a){if(-1!==b.mappedIndexOf(a))throw Error("There already is an object with the key that you specified.");var c=h()?x(a):a;u()&&(a=v(c,a),e.isWriteableObservable(c)?c(a):c=a);b.push(c);return c});n=C(e.utils.unwrapObservable(b),m).sort();g=C(c,m);s&&g.sort();s=e.utils.compareArrays(n,g);n={};var J,A=e.utils.unwrapObservable(c),
|
|
y={},z=!0,g=0;for(J=A.length;g<J;g++){var r=m(A[g]);if(void 0===r||r instanceof Object){z=!1;break}y[r]=A[g]}var A=[],B=0,g=0;for(J=s.length;g<J;g++){var r=s[g],q,w=l+"["+g+"]";switch(r.status){case "added":var D=z?y[r.value]:K(e.utils.unwrapObservable(c),r.value,m);q=F(void 0,D,a,d,b,w,k);h()||(q=e.utils.unwrapObservable(q));w=O(e.utils.unwrapObservable(c),D,n);q===N?B++:A[w-B]=q;n[w]=!0;break;case "retained":D=z?y[r.value]:K(e.utils.unwrapObservable(c),r.value,m);q=K(b,r.value,m);F(q,D,a,d,b,w,
|
|
k);w=O(e.utils.unwrapObservable(c),D,n);A[w]=q;n[w]=!0;break;case "deleted":q=K(b,r.value,m)}t.push({event:r.status,item:q})}b(A);a[d]&&a[d].arrayChanged&&e.utils.arrayForEach(t,function(b){a[d].arrayChanged(b.event,b.item)})}else if(P(c)){b=e.utils.unwrapObservable(b);if(!b){if(h())return s=x(),u()&&(s=v(s)),s;if(u())return v(s);b={}}u()&&(b=v(b));I.save(c,b);if(u())return b;Q(c,function(d){var f=l.length?l+"."+d:d;if(-1==e.utils.arrayIndexOf(a.ignore,f))if(-1!=e.utils.arrayIndexOf(a.copy,f))b[d]=
|
|
c[d];else if("object"!=typeof c[d]&&"array"!=typeof c[d]&&0<a.observe.length&&-1==e.utils.arrayIndexOf(a.observe,f))b[d]=c[d],a.copiedProperties[f]=!0;else{var g=I.get(c[d]),k=F(b[d],c[d],a,d,b,f,b),g=g||k;if(0<a.observe.length&&-1==e.utils.arrayIndexOf(a.observe,f))b[d]=g(),a.copiedProperties[f]=!0;else{if(e.isWriteableObservable(b[d])){if(g=e.utils.unwrapObservable(g),b[d]()!==g)b[d](g)}else g=void 0===b[d]?g:e.utils.unwrapObservable(g),b[d]=g;a.mappedProperties[f]=!0}}})}else switch(f.getType(c)){case "function":u()?
|
|
e.isWriteableObservable(c)?(c(v(c)),b=c):b=v(c):b=c;break;default:if(e.isWriteableObservable(b))return q=u()?v(b):e.utils.unwrapObservable(c),b(q),q;h()||u();b=h()?x():e.observable(e.utils.unwrapObservable(c));u()&&b(v(b))}return b}function O(b,c,a){for(var d=0,e=b.length;d<e;d++)if(!0!==a[d]&&b[d]===c)return d;return null}function R(b,c){var a;c&&(a=c(b));"undefined"===f.getType(a)&&(a=b);return e.utils.unwrapObservable(a)}function K(b,c,a){b=e.utils.unwrapObservable(b);for(var d=0,f=b.length;d<
|
|
f;d++){var l=b[d];if(R(l,a)===c)return l}throw Error("When calling ko.update*, the key '"+c+"' was not found!");}function C(b,c){return e.utils.arrayMap(e.utils.unwrapObservable(b),function(a){return c?R(a,c):a})}function Q(b,c){if("array"===f.getType(b))for(var a=0;a<b.length;a++)c(a);else for(a in b)c(a)}function P(b){var c=f.getType(b);return("object"===c||"array"===c)&&null!==b}function T(){var b=[],c=[];this.save=function(a,d){var f=e.utils.arrayIndexOf(b,a);0<=f?c[f]=d:(b.push(a),c.push(d))};
|
|
this.get=function(a){a=e.utils.arrayIndexOf(b,a);return 0<=a?c[a]:void 0}}function S(){var b={},c=function(a){var c;try{c=a}catch(e){c="$$$"}a=b[c];void 0===a&&(a=new T,b[c]=a);return a};this.save=function(a,b){c(a).save(a,b)};this.get=function(a){return c(a).get(a)}}var p="__ko_mapping__",H=e.dependentObservable,B=0,G,I,L=["create","update","key","arrayChanged"],N={},x={include:["_destroy"],ignore:[],copy:[],observe:[]},j=x;f.isMapped=function(b){return(b=e.utils.unwrapObservable(b))&&b[p]};f.fromJS=
|
|
function(b){if(0==arguments.length)throw Error("When calling ko.fromJS, pass the object you want to convert.");try{B++||(G=[],I=new S);var c,a;2==arguments.length&&(arguments[1][p]?a=arguments[1]:c=arguments[1]);3==arguments.length&&(c=arguments[1],a=arguments[2]);a&&(c=E(c,a[p]));c=z(c);var d=F(a,b,c);a&&(d=a);if(!--B)for(;G.length;){var e=G.pop();e&&(e(),e.__DO.throttleEvaluation=e.throttleEvaluation)}d[p]=E(d[p],c);return d}catch(f){throw B=0,f;}};f.fromJSON=function(b){var c=e.utils.parseJson(b);
|
|
arguments[0]=c;return f.fromJS.apply(this,arguments)};f.updateFromJS=function(){throw Error("ko.mapping.updateFromJS, use ko.mapping.fromJS instead. Please note that the order of parameters is different!");};f.updateFromJSON=function(){throw Error("ko.mapping.updateFromJSON, use ko.mapping.fromJSON instead. Please note that the order of parameters is different!");};f.toJS=function(b,c){j||f.resetDefaultOptions();if(0==arguments.length)throw Error("When calling ko.mapping.toJS, pass the object you want to convert.");
|
|
if("array"!==f.getType(j.ignore))throw Error("ko.mapping.defaultOptions().ignore should be an array.");if("array"!==f.getType(j.include))throw Error("ko.mapping.defaultOptions().include should be an array.");if("array"!==f.getType(j.copy))throw Error("ko.mapping.defaultOptions().copy should be an array.");c=z(c,b[p]);return f.visitModel(b,function(a){return e.utils.unwrapObservable(a)},c)};f.toJSON=function(b,c){var a=f.toJS(b,c);return e.utils.stringifyJson(a)};f.defaultOptions=function(){if(0<arguments.length)j=
|
|
arguments[0];else return j};f.resetDefaultOptions=function(){j={include:x.include.slice(0),ignore:x.ignore.slice(0),copy:x.copy.slice(0)}};f.getType=function(b){if(b&&"object"===typeof b){if(b.constructor===Date)return"date";if(b.constructor===Array)return"array"}return typeof b};f.visitModel=function(b,c,a){a=a||{};a.visitedObjects=a.visitedObjects||new S;var d,k=e.utils.unwrapObservable(b);if(P(k))a=z(a,k[p]),c(b,a.parentName),d="array"===f.getType(k)?[]:{};else return c(b,a.parentName);a.visitedObjects.save(b,
|
|
d);var l=a.parentName;Q(k,function(b){if(!(a.ignore&&-1!=e.utils.arrayIndexOf(a.ignore,b))){var j=k[b],g=a,h=l||"";"array"===f.getType(k)?l&&(h+="["+b+"]"):(l&&(h+="."),h+=b);g.parentName=h;if(!(-1===e.utils.arrayIndexOf(a.copy,b)&&-1===e.utils.arrayIndexOf(a.include,b)&&k[p]&&k[p].mappedProperties&&!k[p].mappedProperties[b]&&k[p].copiedProperties&&!k[p].copiedProperties[b]&&"array"!==f.getType(k)))switch(f.getType(e.utils.unwrapObservable(j))){case "object":case "array":case "undefined":g=a.visitedObjects.get(j);
|
|
d[b]="undefined"!==f.getType(g)?g:f.visitModel(j,c,a);break;default:d[b]=c(j,a.parentName)}}});return d}});
|