Last active
February 20, 2022 03:15
-
-
Save jasonhofer/d8d9f6d5feb160b9a28b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!(function () { | |
// Allow: <!--{ fullName }--> | |
// Instead of: <!-- ko text: fullName --><!-- /ko --> | |
// See: https://knockoutjs.com/documentation/binding-preprocessing.html | |
ko.bindingProvider.instance.preprocessNode = function (node) { | |
if (node.nodeType !== Node.COMMENT_NODE) { | |
return; | |
} | |
const match = node.nodeValue.match(/^[{](.*)[}]$/); | |
if (!match) { return; } | |
// Create a pair of comments to replace the single comment | |
const c1 = document.createComment(`ko text: ${match[1]}`); | |
const c2 = document.createComment('/ko'); | |
node.parentNode.insertBefore(c1, node); | |
node.parentNode.replaceChild(c2, node); | |
// Tell Knockout about the new nodes so that it can apply bindings to them | |
return [c1, c2]; | |
}; | |
ko.extenders['type'] = function (target, type) { | |
var abbrev = {'int': 'integer', 'num': 'number', 'bool': 'boolean'}; | |
type = abbrev[type] || type; | |
var cast = ko.extenders['type'].casters[type]; | |
if (!cast) { throw new Error('Unknown type: ' + type); } | |
var read = function () { return cast(target()); }; | |
if (ko.isWriteableObservable(target)) { | |
var computed = ko.pureComputed({ | |
read: read, | |
write: function (newValue) { target(cast(newValue)); }, | |
}); | |
computed(target()); | |
if ('integer' === type || 'number' === type) { | |
computed.increment = function (amt) { if (null == amt) { amt = 1; } return computed(computed() + cast(amt)); }; | |
computed.decrement = function (amt) { if (null == amt) { amt = 1; } return computed(computed() - cast(amt)); }; | |
} | |
} else { | |
var computed = ko.pureComputed(read); | |
} | |
computed.cast = cast; | |
return computed; | |
}; | |
ko.extenders['type'].casters = { | |
'number': function (n) { return (+ko.unwrap(n) || 0); }, | |
'integer': function (i) { return ~~ko.unwrap(i); }, | |
'boolean': function (b) { return !!ko.unwrap(b); }, | |
'string': function (s) { s = ko.unwrap(s); return '' + (0 === s || false === s ? s : (s || '')); } | |
}; | |
ko.extenders['enum'] = function (target, validValues) { | |
target = target.extend({'type': 'string'}); | |
var isValid = function (value) { return validValues.indexOf(value) >= 0; }, | |
write = function (newValue) { | |
newValue = target.cast(newValue); | |
if (!isValid(newValue)) { | |
throw Error("Invalid enum value: '" + newValue + "'. Expected one of: '" + (validValues.join("', '")) + "'."); | |
} | |
target(newValue); | |
}, | |
initialValue = target(); | |
initialValue && write(initialValue); // Initialize with current value, but allow empty | |
var computed = ko.pureComputed({read: target, write: write}); | |
computed.values = validValues; | |
computed.isValid = isValid; | |
return computed; | |
}; | |
// | |
// Auto-casting observables. | |
// | |
ko.observableNumber = function (initialValue) { | |
return ko.observable(initialValue).extend({'type': 'number'}); | |
}; | |
ko.observableNumber.cast = ko.extenders['type'].casters['number']; | |
ko.observableInt = function (initialValue) { | |
return ko.observable(initialValue).extend({'type': 'integer'}); | |
}; | |
ko.observableInt.cast = ko.extenders['type'].casters['integer']; | |
ko.observableString = function (initialValue) { | |
return ko.observable(initialValue).extend({'type': 'string'}); | |
}; | |
ko.observableString.cast = ko.extenders['type'].casters['string']; | |
ko.observableBool = function (initialValue) { | |
return ko.observable(initialValue).extend({'type': 'boolean'}); | |
}; | |
ko.observableBool.cast = ko.extenders['type'].casters['boolean']; | |
ko.observableEnum = function (validValues, initialValue) { | |
return ko.observable(initialValue).extend({'enum': validValues}); | |
}; | |
// | |
// From: https://gist.github.com/lelandrichardson/9359228 | |
// Old URL: http://tech.pro/blog/1863/10-knockout-binding-handlers-i-don-t-want-to-live-without | |
// | |
ko.bindingHandlers.stopBinding = { | |
init: function () { return { controlsDescendantBindings: true }; } | |
}; | |
ko.virtualElements.allowedBindings.stopBinding = true; | |
ko.bindingHandlers.hidden = { | |
update: function (element, valueAccessor) { | |
ko.bindingHandlers.visible.update(element, function () { | |
return !ko.unwrap(valueAccessor()); | |
}); | |
} | |
}; | |
ko.bindingHandlers.toggle = { | |
init: function (element, valueAccessor) { | |
var observable = valueAccessor(); | |
ko.applyBindingsToNode(element, { | |
click: function () { observable(!observable()); } | |
}); | |
} | |
}; | |
ko.bindingHandlers.href = { | |
update: function (element, valueAccessor) { | |
ko.bindingHandlers.attr.update(element, function () { | |
return { href: valueAccessor() }; | |
}); | |
} | |
}; | |
ko.bindingHandlers.src = { | |
update: function (element, valueAccessor) { | |
ko.bindingHandlers.attr.update(element, function () { | |
return { src: valueAccessor() }; | |
}); | |
} | |
}; | |
ko.bindingHandlers.toJSON = { | |
update: function (element, valueAccessor) { | |
return ko.bindingHandlers.text.update(element, function () { | |
return ko.toJSON(valueAccessor(), null, 4); | |
}); | |
} | |
}; | |
/* | |
ko.bindingHandlers.instantValue = { // Same as textInput. Saving this for reference. | |
init: function (element, valueAccessor, allBindingsAccessor) { | |
handlers.value.init(element, valueAccessor, | |
ko.observable(ko.utils.extend(allBindingsAccessor(), {valueUpdate: 'afterkeydown'})) | |
); | |
}, | |
update: handlers.value.update | |
}; | |
*/ | |
// See: https://github.com/mbest/knockout/issues/9 | |
// Formerly "withlight" | |
ko.bindingHandlers['context'] = { | |
'init': function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { | |
var bindingValue = valueAccessor(); | |
if (typeof bindingValue !== 'object' || bindingValue === null) { | |
throw new Error('The "context" binding must be used with an object'); | |
} | |
var innerContext = bindingContext['createChildContext'](bindingValue); | |
ko.applyBindingsToDescendants(innerContext, element); | |
return {'controlsDescendantBindings': true}; | |
} | |
}; | |
// my own | |
ko.bindingHandlers.id = { | |
update: function (element, valueAccessor) { | |
ko.bindingHandlers.attr.update(element, function () { | |
return { id: valueAccessor() }; | |
}); | |
} | |
}; | |
ko.bindingHandlers.required = { | |
update: function (element, valueAccessor) { | |
var accessor = function () { return { required: valueAccessor() }; }; | |
ko.bindingHandlers.attr.update(element, accessor); | |
ko.bindingHandlers.css.update(element, accessor); | |
} | |
}; | |
ko.bindingHandlers.readOnly = { | |
update: function (element, valueAccessor) { | |
ko.bindingHandlers.attr.update(element, function () { | |
return { readOnly: valueAccessor() }; | |
}); | |
} | |
}; | |
ko.bindingHandlers.enterKey = { | |
init: function (element, valueAccessor, allBindings, viewModel) { | |
ko.utils.registerEventHandler(element, 'keypress', function (event) { | |
if (13 === (event.which || event.keyCode)) { | |
ko.utils.triggerEvent(element, 'blur'); | |
valueAccessor().call(viewModel, viewModel, event); | |
ko.utils.triggerEvent(element, 'focus'); | |
return false; | |
} | |
return true; | |
}); | |
} | |
}; | |
/* | |
ko.bindingHandlers.fadeInVisible = { | |
init: function (element, valueAccessor) { | |
// Initially set the element to be instantly visible/hidden depending on the value | |
var value = valueAccessor(); | |
$(element).toggle(ko.unwrap(value)); | |
}, | |
update: function (element, valueAccessor) { | |
// Whenever the value subsequently changes, slowly fade the element in or out | |
var value = valueAccessor(); | |
ko.unwrap(value) ? $(element).fadeIn() : $(element).hide(); | |
} | |
}; | |
ko.bindingHandlers.fadeInHidden = { | |
init: function (element, valueAccessor) { | |
// Initially set the element to be instantly visible/hidden depending on the value | |
var value = valueAccessor(); | |
$(element).toggle(!ko.unwrap(value)); | |
}, | |
update: function (element, valueAccessor) { | |
// Whenever the value subsequently changes, slowly fade the element in or out | |
var value = valueAccessor(); | |
ko.unwrap(value) ? $(element).hide() : $(element).fadeIn(); | |
} | |
}; | |
*/ | |
// | |
// HTML5 | |
// | |
ko.bindingHandlers.contentEditable = { | |
init: function (element, valueAccessor) { | |
var value = valueAccessor(); | |
element.setAttribute('contentEditable', true); | |
if (ko.isWritableObservable(value)) { | |
ko.utils.registerEventHandler(element, 'blur', function () { | |
value(element.innerText); | |
}); | |
} | |
}, | |
update: function (element, valueAccessor) { | |
ko.utils.setTextContent(element, ko.unwrap(valueAccessor())); | |
} | |
}; | |
// | |
// Debugging | |
// | |
ko.bindingHandlers.consoleLog = { | |
init: function (element, valueAccessor, allBindingsAccessor) { | |
var value = valueAccessor(), | |
bindings = allBindingsAccessor(); | |
if (!bindings.hasOwnProperty('unwrap') || bindings.unwrap) { | |
value = ko.unwrap(value); | |
} | |
console.log(value); | |
} | |
}; | |
ko.bindingHandlers.consoleDebug = { | |
init: function (element, valueAccessor, allBindingsAccessor) { | |
var value = valueAccessor(), | |
bindings = allBindingsAccessor(); | |
if (!bindings.hasOwnProperty('unwrap') || bindings.unwrap) { | |
value = ko.unwrap(value); | |
} | |
console.debug(value); | |
} | |
}; | |
ko.bindingHandlers.consoleDir = { | |
init: function (element, valueAccessor, allBindingsAccessor) { | |
var value = valueAccessor(), | |
bindings = allBindingsAccessor(); | |
if (!bindings.hasOwnProperty('unwrap') || bindings.unwrap) { | |
value = ko.unwrap(value); | |
} | |
console.dir(value); | |
} | |
}; | |
ko.bindingHandlers.globalize = { | |
init: function (element, valueAccessor, allBindingsAccessor, viewModel) { | |
var value = valueAccessor(), | |
bindings = allBindingsAccessor(); | |
if (!bindings.hasOwnProperty('unwrap') || bindings.unwrap) { | |
value = ko.unwrap(value); | |
} | |
window.koElement = element; | |
window.koValue = value; | |
window.koBindings = bindings; | |
window.koViewModel = viewModel; | |
} | |
}; | |
// | |
// Vendor Dependent | |
// | |
ko.bindingHandlers.markdown = { | |
init: function () { return { controlsDescendantBindings: true }; }, | |
update: function (element, valueAccessor) { | |
ko.utils.setHtml(element, markdownit().render(ko.unwrap(valueAccessor()))); | |
} | |
}; | |
ko.bindingHandlers.fromNow = { | |
update: function (element, valueAccessor) { | |
var fromNow, m, value; | |
value = ko.unwrap(valueAccessor()); | |
fromNow = (function () { | |
try { | |
m = moment(value); | |
if (m.isValid()) { | |
return m.fromNow(); | |
} else { | |
return ''; | |
} | |
} catch (_error) { | |
return ''; | |
} | |
})(); | |
return ko.bindingHandlers.text.update(element, function () { return fromNow; }); | |
} | |
}; | |
ko.bindingHandlers.blockUi = { | |
update: function (element, valueAccessor, allBindingsAccessor) { | |
var bindings = allBindingsAccessor(), | |
message = bindings.message || null; | |
//$.blockUI.defaults.css = {}; | |
if (ko.unwrap(valueAccessor())) { | |
$(element).block({ | |
message: message, | |
overlayCSS: { | |
opacity: 0.25 | |
} | |
}); | |
} else { | |
$(element).unblock(); | |
} | |
} | |
}; | |
// FX | |
ko.bindingHandlers.textFadeIn = { | |
update: function (element, valueAccessor) { | |
var $el = $(element); | |
$el.hide(); | |
ko.bindingHandlers.text.update(element, valueAccessor); | |
$el.fadeIn('slow'); | |
} | |
}; | |
// Simple Select2 | |
// Basic usage: <select data-bind="value: myValue, options: myOptions, select2"></select> | |
ko.bindingHandlers.select2 = { | |
init: function (element, valueAccessor, allBindingsAccessor) { | |
var $el = $(element), | |
options = valueAccessor() || {}, | |
bindings = allBindingsAccessor() || {}; | |
$el.select2(options); | |
if (bindings.value && ko.isSubscribable(bindings.value)) { | |
bindings.value.subscribe(function () { | |
$el.trigger('change'); | |
}); | |
} | |
ko.utils.domNodeDisposal.addDisposeCallback(element, function () { | |
$el.select2('destroy'); | |
}); | |
} | |
}; | |
function getSharedMixin(parentMixin) { | |
return { | |
alias: function (observable) { | |
var computed = ko.pureComputed({ | |
read: function () { return observable(); }, | |
write: function (value) { observable(value); return this; } | |
}, this); | |
return ko.utils.extend(computed, parentMixin); | |
}, | |
empty: function () { | |
var computed = ko.pureComputed(function () { | |
return ko.utils.isEmpty(this()); | |
}, this); | |
return ko.utils.extend(computed, parentMixin); | |
}, | |
notEmpty: function () { | |
var computed = ko.pureComputed(function () { | |
return !ko.utils.isEmpty(this()); | |
}, this); | |
return ko.utils.extend(computed, parentMixin); | |
} | |
}; | |
} | |
var observableMixin = { | |
oneWay: function (observable) { | |
var reader = ko.observable(observable), | |
computed = ko.pureComputed({ | |
read: function () { return reader()(); }, | |
write: function (value) { this(value); reader(this); return this; } | |
}, this); | |
return ko.utils.extend(computed, observableMixin); | |
}, | |
and: function () { | |
var computed = ko.pureComputed(function () { | |
if (!this()) return false; | |
for (var i in arguments) { | |
if (!ko.unwrap(arguments[i])) { | |
return false; | |
} | |
} | |
return true; | |
}, this); | |
return ko.utils.extend(computed, observableMixin); | |
}, | |
or: function () { | |
var computed = ko.pureComputed(function () { | |
if (this()) return true; | |
for (var i in arguments) { | |
if (ko.unwrap(arguments[i])) { | |
return true; | |
} | |
} | |
return false; | |
}, this); | |
return ko.utils.extend(computed, observableMixin); | |
}, | |
bool: function () { | |
var computed = ko.pureComputed(function () { | |
return !!this(); | |
}, this); | |
return ko.utils.extend(computed, observableMixin); | |
}, | |
not: function () { | |
var computed = ko.pureComputed(function () { | |
return !this(); | |
}, this); | |
return ko.utils.extend(computed, observableMixin); | |
}, | |
none: function () { | |
var computed = ko.pureComputed(function () { | |
return this() == null; | |
}, this); | |
return ko.utils.extend(computed, observableMixin); | |
}, | |
equal: function (value) { | |
var computed = ko.pureComputed(function () { | |
return this() === ko.unwrap(value); | |
}, this); | |
return ko.utils.extend(computed, observableMixin); | |
}, | |
gt: function (value) { | |
var computed = ko.pureComputed(function () { | |
return this() > ko.unwrap(value); | |
}, this); | |
return ko.utils.extend(computed, observableMixin); | |
}, | |
gte: function (value) { | |
var computed = ko.pureComputed(function () { | |
return this() >= ko.unwrap(value); | |
}, this); | |
return ko.utils.extend(computed, observableMixin); | |
}, | |
lt: function (value) { | |
var computed = ko.pureComputed(function () { | |
return this() < ko.unwrap(value); | |
}, this); | |
return ko.utils.extend(computed, observableMixin); | |
}, | |
lte: function (value) { | |
var computed = ko.pureComputed(function () { | |
return this() <= ko.unwrap(value); | |
}, this); | |
return ko.utils.extend(computed, observableMixin); | |
}, | |
add: function (amount) { | |
var computed = ko.pureComputed(function () { | |
return this() + ko.observableNumber.cast(ko.unwrap(amount)); | |
}, this); | |
return ko.utils.extend(computed, observableMixin); | |
}, | |
subtract: function (amount) { | |
var computed = ko.pureComputed(function () { | |
return this() - ko.observableNumber.cast(ko.unwrap(amount)); | |
}, this); | |
return ko.utils.extend(computed, observableMixin); | |
}, | |
match: function (regex) { | |
var computed = ko.pureComputed(function () { | |
return ko.unwrap(regex).test(this()); | |
}, this); | |
return ko.utils.extend(computed, observableMixin); | |
}, | |
ceil: function (divisor) { | |
var computed = ko.pureComputed(function () { | |
return Math.ceil(this() / ko.unwrap(divisor)); | |
}, this); | |
return ko.utils.extend(computed, observableMixin); | |
}, | |
floor: function (divisor) { | |
var computed = ko.pureComputed(function () { | |
return Math.floor(this() / ko.unwrap(divisor)); | |
}, this); | |
return ko.utils.extend(computed, observableMixin); | |
}, | |
get: function (property, defaultValue) { | |
var unwrap = ko.unwrap, | |
isNone = ko.utils.isNone, | |
computed = ko.pureComputed(function () { | |
var value = this(); | |
if (isNone(value)) { return defaultValue; } | |
var parts = ko.observableString.cast(property).split('.'), | |
next; | |
while (parts.length) { | |
next = parts.shift(); | |
if (typeof value !== 'object' || !value.hasOwnProperty(next)) { | |
return defaultValue; | |
} | |
value = unwrap(value[next]); | |
if (isNone(value)) { return defaultValue; } | |
} | |
return value; | |
}, this); | |
return ko.utils.extend(computed, observableMixin); | |
} | |
}; | |
ko.utils.extend(observableMixin, getSharedMixin(observableMixin)); | |
ko.utils.extend(ko.observable.fn, observableMixin); | |
// requires knockout-projections.js | |
var observableArrayMixin = { | |
filterBy: function (property, value) { | |
if (arguments.length === 1) { | |
value = true; | |
} | |
var computed = this.filter(function (item) { | |
return ko.unwrap(item[property]) === ko.unwrap(value); | |
}); | |
return ko.utils.extend(computed, observableArrayMixin); | |
}, | |
mapBy: function (property) { | |
var computed = this.map(function (item) { return ko.unwrap(item[property]); }); | |
return ko.utils.extend(computed, observableArrayMixin); | |
}, | |
paged: function (offset, limit) { | |
var computed = ko.pureComputed(function () { | |
var offsetVal = ko.unwrap(offset), | |
limitVal = ko.unwrap(limit); | |
return this().slice(offsetVal * limitVal, offsetVal * limitVal + limitVal); | |
}, this); | |
return ko.utils.extend(computed, observableArrayMixin); | |
}, | |
count: function () { | |
var computed = ko.pureComputed(function () { | |
return this().length; | |
}, this); | |
return ko.utils.extend(computed, observableMixin); | |
}, | |
contains: function (value) { | |
var computed = ko.pureComputed(function () { | |
return ko.utils.arrayIndexOf(this(), ko.unwrap(value)) >= 0; | |
}, this); | |
return ko.utils.extend(computed, observableMixin); | |
}, | |
uniq: function () { | |
var computed = ko.pureComputed(function () { | |
return ko.utils.arrayGetDistinctValues(this()); | |
}, this); | |
return ko.utils.extend(computed, observableArrayMixin); | |
}, | |
intersect: function (other) { | |
var computed = ko.pureComputed(function () { | |
var args = [this()]; | |
ko.utils.arrayPushAll(args, ko.utils.arrayMap(ko.utils.args(arguments), ko.unwrap)); | |
return ko.utils.arrayIntersect.apply(null, args); | |
}, this); | |
return ko.utils.extend(computed, observableArrayMixin); | |
}, | |
// http://stackoverflow.com/questions/12166982 | |
subscribeArrayChanged: function (onAdded, onDeleted) { | |
var previousValue; | |
this.subscribe(function (oldValue) { | |
previousValue = oldValue.slice(0); // store a clone of the array | |
}, null, 'beforeChange'); | |
this.subscribe(function (newValue) { | |
var edits = ko.utils.compareArrays(previousValue, newValue); | |
for (var i = 0, j = edits.length; i < j; ++i) { | |
var edit = edits[i]; | |
switch (edit.status) { | |
case 'retained': break; | |
case 'deleted': if (onDeleted) { onDeleted(edit.value, edit.index); } break; | |
case 'added': if (onAdded) { onAdded(edit.value, edit.index); } break; | |
} | |
} | |
previousValue = void(0); | |
}); | |
} | |
}; | |
ko.utils.extend(observableArrayMixin, getSharedMixin(observableArrayMixin)); | |
ko.utils.extend(ko.observableArray.fn, observableArrayMixin); | |
ko.extenders.min = function (target, min) { | |
return ko.pureComputed({ | |
read: target, | |
write: function (value) { | |
var current = target(); | |
value = Math.max(value, ko.unwrap(min)); | |
if (value !== current) { | |
target(value); | |
} | |
} | |
}); | |
}; | |
ko.extenders.max = function (target, max) { | |
return ko.pureComputed({ | |
read: target, | |
write: function (value) { | |
var current = target(); | |
value = Math.min(value, ko.unwrap(max)); | |
if (value !== current) { | |
target(value); | |
} | |
} | |
}); | |
}; | |
ko.utils.args = function (args, sliceAt) { | |
return Array.prototype.slice.call(args, 1 === arguments.length ? 0 : ~~sliceAt); | |
}; | |
ko.utils.getType = function (obj) { | |
switch (true) { | |
case ko.utils.isArray(obj): return 'array'; | |
case ko.utils.isFunction(obj): return 'function'; | |
case ko.utils.isObject(obj): return 'object'; | |
default: return gettype(ko.unwrap(obj)); | |
} | |
}; | |
// See https://github.com/kvz/locutus/blob/master/src/php/var/is_array.js | |
ko.utils.isArray = function (obj) { | |
obj = ko.unwrap(obj); | |
return !!obj && typeof obj === 'object' && typeof obj.length === 'number' && Object.prototype.toString.call(obj) === '[object Array]'; | |
/* This seems pretty intense, but if you need to be absolutely sure and without a doubt, I guess it would be the only way. | |
var len = obj.length; | |
obj[obj.length] = 'bogus'; | |
if (len !== obj.length) { | |
obj.length -= 1; | |
return true; | |
} | |
delete obj[obj.length]; | |
return false; | |
*/ | |
}; | |
// See https://github.com/kvz/locutus/blob/master/src/php/var/is_object.js | |
ko.utils.isObject = function (obj) { | |
if (ko.utils.isArray(obj)) { | |
return false | |
} | |
obj = ko.unwrap(obj); | |
return obj !== null && typeof obj === 'object' | |
}; | |
// See https://github.com/lodash/lodash => _.isFunction() | |
ko.utils.isFunction = function (obj) { | |
obj = ko.unwrap(obj); | |
if ('function' === typeof obj) { | |
return true; | |
} | |
var tag = ko.utils.isObject(obj) ? Object.prototype.toString.call(obj) : ''; | |
return '[object Function]' === tag || '[object GeneratorFunction]' === tag; | |
}; | |
ko.utils.isNone = function (obj) { | |
var undef; | |
obj = ko.unwrap(obj); | |
return (null === obj || undef === obj); | |
}; | |
ko.utils.isEmptyObject = function (obj) { | |
var name; | |
for (name in ko.unwrap(obj)) { | |
return false; | |
} | |
return true; | |
}; | |
ko.utils.isEmpty = function (obj) { | |
obj = ko.unwrap(obj); | |
if (ko.utils.isNone(obj) || '' === obj) { | |
return true; | |
} | |
if (ko.utils.isArray(obj)) { | |
return 0 === obj.length; | |
} | |
if (ko.utils.isObject(obj)) { | |
return ko.utils.isEmptyObject(obj); | |
} | |
return false; | |
}; | |
ko.utils.arrayIntersect = function () { | |
var args = ko.utils.args(arguments), | |
intersect = function (a, b) { | |
var result = []; | |
a = a.slice(0).sort(); | |
b = b.slice(0).sort(); | |
while (a.length > 0 && b.length > 0) { | |
if (a[0] < b[0]) { a.shift(); } | |
else if (a[0] > b[0]) { b.shift(); } | |
else { /* they're equal */ | |
result.push(a.shift()); | |
b.shift(); | |
} | |
} | |
return result; | |
}, | |
a = args.shift() || [], | |
b = args.shift() || [], | |
result = intersect(a, b); | |
while (args.length > 0) { | |
result = intersect(result, args.shift() || []); | |
} | |
return result; | |
}; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment