diff --git a/vendors/bootstrap/js/bootstrap.native.js b/vendors/bootstrap/js/bootstrap.native.js index 335daaf63..5a94d7722 100644 --- a/vendors/bootstrap/js/bootstrap.native.js +++ b/vendors/bootstrap/js/bootstrap.native.js @@ -5,7 +5,9 @@ */ (doc => { - const setFocus = element => element.focus ? element.focus() : element.setActive(); + const + setFocus = element => element.focus ? element.focus() : element.setActive(), + isArrow = e => 'ArrowUp' === e.key || 'ArrowDown' === e.key; this.BSN = { Dropdown: function(toggleBtn) { @@ -13,11 +15,11 @@ const self = this, parent = toggleBtn.parentNode, preventEmptyAnchor = e => { - const t = e.target, href = t.href || (t.parentNode && t.parentNode.href); - (href && href.slice(-1) === '#') && e.preventDefault(); + const t = e.target; + ('#' === (t.href || t.parentNode?.href)?.slice(-1)) && e.preventDefault(); }, open = bool => { - menu && menu.classList.toggle('show', bool); + menu?.classList.toggle('show', bool); parent.classList.toggle('show', bool); toggleBtn.setAttribute('aria-expanded', bool); toggleBtn.open = bool; @@ -28,14 +30,14 @@ } }, toggleEvents = () => { - let action = (toggleBtn.open ? 'add' : 'remove') + 'EventListener'; + const action = (toggleBtn.open ? 'add' : 'remove') + 'EventListener'; doc[action]('click',dismissHandler); doc[action]('keydown',preventScroll); doc[action]('keyup',keyHandler); doc[action]('focus',dismissHandler); }, dismissHandler = e => { - let eventTarget = e.target; + const eventTarget = e.target; if ((!menu.contains(eventTarget) && !toggleBtn.contains(eventTarget)) || e.type !== 'focus') { self.hide(); preventEmptyAnchor(e); @@ -45,18 +47,19 @@ self.show(); preventEmptyAnchor(e); }, - preventScroll = e => (e.key === 'ArrowUp' || e.key === 'ArrowDown') && e.preventDefault(), + preventScroll = e => isArrow(e) && e.preventDefault(), keyHandler = e => { - if (e.key === 'Escape') { + if ('Escape' === e.key) { self.toggle(); - } else if (e.key === 'ArrowUp' || e.key === 'ArrowDown') { + } else if (isArrow(e)) { let activeItem = doc.activeElement, isMenuButton = activeItem === toggleBtn, idx = isMenuButton ? 0 : menuItems.indexOf(activeItem); if (parent.contains(activeItem)) { if (!isMenuButton) { - idx = e.key === 'ArrowUp' ? (idx > 1 ? idx-1 : 0) - : e.key === 'ArrowDown' ? (idx < menuItems.length-1 ? idx+1 : idx) : idx; + idx = 'ArrowUp' === e.key + ? (idx > 1 ? idx-1 : 0) + : (idx < menuItems.length-1 ? idx+1 : idx); } menuItems[idx] && setFocus(menuItems[idx]); } else { diff --git a/vendors/jua/jua.js b/vendors/jua/jua.js index 387114205..7e27a26ab 100644 --- a/vendors/jua/jua.js +++ b/vendors/jua/jua.js @@ -10,7 +10,7 @@ */ getDataFromFiles = (aItems, fFileCallback, iLimit, fLimitCallback) => { - if (aItems && aItems.length) + if (aItems?.length) { let oFile, @@ -261,7 +261,7 @@ */ runEvent(sName, ...aArgs) { - this.oEvents[sName] && this.oEvents[sName].apply(null, aArgs); + this.oEvents[sName]?.apply(null, aArgs); } /** @@ -392,7 +392,7 @@ self.generateNewInput(oClickElement); }, 10); }; - if (oInput.files && oInput.files.length) { + if (oInput.files?.length) { getDataFromFiles(oInput.files, fFileCallback, limit, self.getEvent('onLimitReached') diff --git a/vendors/knockout/Gruntfile.js b/vendors/knockout/Gruntfile.js index c5d7c0a70..079572796 100644 --- a/vendors/knockout/Gruntfile.js +++ b/vendors/knockout/Gruntfile.js @@ -63,8 +63,8 @@ module.exports = function(grunt) { function buildMin(output, done) { var cc = require('closure-compiler'); var options = { - language_in:'ECMASCRIPT_2018', - language_out:'ECMASCRIPT_2018', + language_in:'ECMASCRIPT_2020', + language_out:'ECMASCRIPT_2020', compilation_level: 'ADVANCED_OPTIMIZATIONS', output_wrapper: '(()=>{%output%})();' }; diff --git a/vendors/knockout/build/output/knockout-latest.debug.js b/vendors/knockout/build/output/knockout-latest.debug.js index c0aba9e20..d182b63b1 100644 --- a/vendors/knockout/build/output/knockout-latest.debug.js +++ b/vendors/knockout/build/output/knockout-latest.debug.js @@ -37,7 +37,7 @@ ko.utils = { // Ensure it's a real array, as we're about to reparent the nodes and // we don't want the underlying collection to change while we're doing that. var nodesArray = [...nodes]; - var templateDocument = (nodesArray[0] && nodesArray[0].ownerDocument) || document; + var templateDocument = nodesArray[0]?.ownerDocument || document; var container = templateDocument.createElement('div'); nodesArray.forEach(node => container.append(ko.cleanNode(node))); @@ -108,7 +108,7 @@ ko.utils = { node.ownerDocument.documentElement.contains(node.nodeType !== 1 ? node.parentNode : node), triggerEvent: (element, eventType) => { - if (!(element && element.nodeType)) + if (!element?.nodeType) throw new Error("element must be a DOM node when calling triggerEvent"); element.dispatchEvent(new Event(eventType)); @@ -134,9 +134,7 @@ ko.utils.domData = { if (dataStore.has(node)) { dataStore.get(node)[key] = value; } else { - let dataForNode = {}; - dataForNode[key] = value; - dataStore.set(node, dataForNode); + dataStore.set(node, {[key]:value}); } return value; }, @@ -238,18 +236,9 @@ ko.exportSymbol('utils.domNodeDisposal.addDisposeCallback', ko.utils.domNodeDisp ko.tasks = (() => { var taskQueue = [], taskQueueLength = 0, - nextHandle = 1, nextIndexToProcess = 0, - // Chrome 27+, Firefox 14+, IE 11+, Opera 15+, Safari 6.1+ - // From https://github.com/petkaantonov/bluebird * Copyright (c) 2014 Petka Antonov * License: MIT - scheduler = (callback => { - var div = document.createElement("div"); - new MutationObserver(callback).observe(div, {attributes: true}); - return () => div.classList.toggle("foo"); - })(scheduledProcess); - - function processTasks() { + processTasks = () => { if (taskQueueLength) { // Each mark represents the end of a logical group of tasks and the number of these groups is // limited to prevent unchecked recursion. @@ -276,34 +265,30 @@ ko.tasks = (() => { } } } - } + }, - function scheduledProcess() { + scheduledProcess = () => { processTasks(); // Reset the queue nextIndexToProcess = taskQueueLength = taskQueue.length = 0; - } + }, - var tasks = { + // Chrome 27+, Firefox 14+, IE 11+, Opera 15+, Safari 6.1+ + // From https://github.com/petkaantonov/bluebird * Copyright (c) 2014 Petka Antonov * License: MIT + scheduler = (callback => { + var div = document.createElement("div"); + new MutationObserver(callback).observe(div, {attributes: true}); + return () => div.classList.toggle("foo"); + })(scheduledProcess); + + return { schedule: func => { - if (!taskQueueLength) { - scheduler(scheduledProcess); - } + taskQueueLength || scheduler(scheduledProcess); taskQueue[taskQueueLength++] = func; - return nextHandle++; - }, - - cancel: handle => { - var index = handle - (nextHandle - taskQueueLength); - if (index >= nextIndexToProcess && index < taskQueueLength) { - taskQueue[index] = null; - } } }; - - return tasks; })(); ko.extenders = { 'debounce': (target, timeout) => target.limit(callback => debounce(callback, timeout)), @@ -554,7 +539,7 @@ ko.subscribable['fn'] = ko_subscribable_fn; ko.isSubscribable = instance => - instance != null && typeof instance.subscribe == "function" && typeof instance.notifySubscribers == "function"; + typeof instance?.subscribe == "function" && typeof instance.notifySubscribers == "function"; (() => { var outerFrames = [], @@ -591,11 +576,11 @@ ko.dependencyDetection = { } }, - getDependenciesCount: () => currentFrame && currentFrame.computed.getDependenciesCount(), + getDependenciesCount: () => currentFrame?.computed.getDependenciesCount(), - isInitial: () => currentFrame && currentFrame.isInitial, + isInitial: () => currentFrame?.isInitial, - computed: () => currentFrame && currentFrame.computed + computed: () => currentFrame?.computed }; })(); @@ -615,11 +600,9 @@ ko.observable = initialValue => { } return this; // Permits chained assignments } - else { - // Read - ko.dependencyDetection.registerDependency(observable); // The caller only needs to be notified of changes if they did a "read" operation - return observable[observableLatestValue]; - } + // Read + ko.dependencyDetection.registerDependency(observable); // The caller only needs to be notified of changes if they did a "read" operation + return observable[observableLatestValue]; } observable[observableLatestValue] = initialValue; @@ -641,7 +624,7 @@ ko.observable = initialValue => { var observableFn = { 'toJSON': function() { let value = this[observableLatestValue]; - return value && value.toJSON ? value.toJSON() : value; + return value?.toJSON?.() || value; }, equalityComparer: valuesArePrimitiveAndEqual, peek: function() { return this[observableLatestValue]; }, @@ -755,7 +738,7 @@ const arrayChangeEventName = 'arrayChange'; ko.extenders['trackArrayChanges'] = (target, options) => { // Use the provided options--each call to trackArrayChanges overwrites the previously set options target.compareArrayOptions = {}; - if (options && typeof options == "object") { + if (typeof options == "object") { ko.utils.extend(target.compareArrayOptions, options); } target.compareArrayOptions['sparse'] = true; @@ -834,7 +817,7 @@ ko.extenders['trackArrayChanges'] = (target, options) => { cachedDiff = null; pendingChanges = 0; - if (changes && changes.length) { + if (changes?.length) { target.notifySubscribers(changes, arrayChangeEventName); } } @@ -950,14 +933,13 @@ ko.computed = (evaluatorFunctionOrOptions, options) => { // Writing a value writeFunction(...arguments); return this; // Permits chained assignments - } else { - // Reading the value - state.isDisposed || ko.dependencyDetection.registerDependency(computedObservable); - if (state.isDirty || (state.isSleeping && computedObservable.haveDependenciesChanged())) { - computedObservable.evaluateImmediate(); - } - return state.latestValue; } + // Reading the value + state.isDisposed || ko.dependencyDetection.registerDependency(computedObservable); + if (state.isDirty || (state.isSleeping && computedObservable.haveDependenciesChanged())) { + computedObservable.evaluateImmediate(); + } + return state.latestValue; } computedObservable[computedState] = state; @@ -1010,9 +992,7 @@ ko.computed = (evaluatorFunctionOrOptions, options) => { // Utility function that disposes a given dependencyTracking entry function computedDisposeDependencyCallback(id, entryToDispose) { - if (entryToDispose !== null && entryToDispose.dispose) { - entryToDispose.dispose(); - } + entryToDispose?.dispose?.(); } // This function gets called each time a dependency is detected while evaluating a computed. @@ -1101,8 +1081,8 @@ var computedFn = { }, markDirty: function () { // Process "dirty" events if we can handle delayed notifications - if (this._evalDelayed && !this[computedState].isBeingEvaluated) { - this._evalDelayed(false /*isChange*/); + if (!this[computedState].isBeingEvaluated) { + this._evalDelayed?.(false /*isChange*/); } }, isActive: function () { @@ -1123,7 +1103,7 @@ var computedFn = { evaluatePossiblyAsync: function () { var computedObservable = this, throttleEvaluationTimeout = computedObservable['throttleEvaluation']; - if (throttleEvaluationTimeout && throttleEvaluationTimeout >= 0) { + if (throttleEvaluationTimeout >= 0) { clearTimeout(this[computedState].evaluationTimeoutInstance); this[computedState].evaluationTimeoutInstance = setTimeout(() => computedObservable.evaluateImmediate(true /*notifyChange*/) @@ -1153,7 +1133,7 @@ var computedFn = { return; } - if (state.disposeWhenNodeIsRemoved && !ko.utils.domNodeIsAttachedToDocument(state.disposeWhenNodeIsRemoved) || disposeWhen && disposeWhen()) { + if (state.disposeWhenNodeIsRemoved && !ko.utils.domNodeIsAttachedToDocument(state.disposeWhenNodeIsRemoved) || disposeWhen?.()) { // See comment above about suppressDisposalUntilDisposeWhenReturnsFalse if (!state.suppressDisposalUntilDisposeWhenReturnsFalse) { computedObservable.dispose(); @@ -1275,7 +1255,7 @@ var computedFn = { var state = this[computedState]; if (!state.isSleeping && state.dependencyTracking) { ko.utils.objectForEach(state.dependencyTracking, (id, dependency) => - dependency.dispose && dependency.dispose() + dependency.dispose?.() ); } if (state.disposeWhenNodeIsRemoved && state.domNodeDisposalCallback) { @@ -1833,10 +1813,17 @@ ko.expressionRewriting = (() => { ko.bindingContext = class { constructor(dataItemOrAccessor, parentContext, dataItemAlias, extendCallback, options) { + var self = this, + shouldInheritData = dataItemOrAccessor === inheritParentVm, + realDataItemOrAccessor = shouldInheritData ? undefined : dataItemOrAccessor, + isFunc = typeof(realDataItemOrAccessor) == "function" && !ko.isObservable(realDataItemOrAccessor), + subscribable, + dataDependency = options && options['dataDependency'], + // The binding context object includes static properties for the current, parent, and root view models. // If a view model is actually stored in an observable, the corresponding binding context object, and // any child contexts, must be updated when the view model is changed. - function updateContext() { + updateContext = () => { // Most of the time, the context will directly get a view model object, but if a function is given, // we call the function to retrieve the view model. If the function accesses any observables or returns // an observable, the dependency is tracked, and those observables can later cause the binding @@ -1891,14 +1878,7 @@ ko.expressionRewriting = (() => { } return self['$data']; - } - - var self = this, - shouldInheritData = dataItemOrAccessor === inheritParentVm, - realDataItemOrAccessor = shouldInheritData ? undefined : dataItemOrAccessor, - isFunc = typeof(realDataItemOrAccessor) == "function" && !ko.isObservable(realDataItemOrAccessor), - subscribable, - dataDependency = options && options['dataDependency']; + }; if (options && options['exportDependencies']) { // The "exportDependencies" option means that the calling code will track any dependencies and re-create @@ -2306,13 +2286,12 @@ ko.expressionRewriting = (() => { })(); (() => { var loadingSubscribablesCache = Object.create(null), // Tracks component loads that are currently in flight - loadedDefinitionsCache = Object.create(null); // Tracks component loads that have already completed + loadedDefinitionsCache = new Map(); // Tracks component loads that have already completed ko.components = { get: (componentName, callback) => { - var cachedDefinition = loadedDefinitionsCache[componentName]; - if (cachedDefinition) { - ko.tasks.schedule(() => callback(cachedDefinition.definition) ); + if (loadedDefinitionsCache.has(componentName)) { + ko.tasks.schedule(() => callback(loadedDefinitionsCache.get(componentName))); } else { // Join the loading process that is already underway, or start a new one. var subscribable = loadingSubscribablesCache[componentName], @@ -2324,8 +2303,8 @@ ko.expressionRewriting = (() => { subscribable = loadingSubscribablesCache[componentName] = new ko.subscribable(); subscribable.subscribe(callback); - beginLoadingComponent(componentName, definition => { - loadedDefinitionsCache[componentName] = { definition: definition }; + loadComponent(componentName, definition => { + loadedDefinitionsCache.set(componentName, definition); delete loadingSubscribablesCache[componentName]; // For API consistency, all loads complete asynchronously. However we want to avoid @@ -2347,9 +2326,6 @@ ko.expressionRewriting = (() => { } }, - clearCachedDefinition: componentName => - delete loadedDefinitionsCache[componentName], - register: (componentName, config) => { if (!config) { throw new Error('Invalid configuration for ' + componentName); @@ -2373,70 +2349,53 @@ ko.expressionRewriting = (() => { // 1. To supply configuration objects from some other source (e.g., conventions) // 2. Or, to resolve configuration objects by loading viewmodels/templates via arbitrary logic. - var defaultConfigRegistry = Object.create(null); - var createViewModelKey = 'createViewModel'; + var defaultConfigRegistry = Object.create(null), + createViewModelKey = 'createViewModel', + throwError = (componentName, message) => { throw new Error(`Component '${componentName}': ${message}`) }, - // Takes a config object of the form { template: ..., viewModel: ... }, and asynchronously convert it - // into the standard component definition format: - // { template: , createViewModel: function(params, componentInfo) { ... } }. - // Since both template and viewModel may need to be resolved asynchronously, both tasks are performed - // in parallel, and the results joined when both are ready. We don't depend on any promises infrastructure, - // so this is implemented manually below. - function loadComponent(componentName, callback) { - var result = {}, - config = defaultConfigRegistry[componentName] || {}, - templateConfig = config['template'], - viewModelConfig = config['viewModel']; + // Takes a config object of the form { template: ..., viewModel: ... }, and asynchronously convert it + // into the standard component definition format: + // { template: , createViewModel: function(params, componentInfo) { ... } }. + // Since both template and viewModel may need to be resolved asynchronously, both tasks are performed + // in parallel, and the results joined when both are ready. We don't depend on any promises infrastructure, + // so this is implemented manually below. + loadComponent = (componentName, callback) => { + // Try the candidates + var result = {}, + config = defaultConfigRegistry[componentName] || {}, + templateConfig = config['template'], + viewModelConfig = config['viewModel']; - if (templateConfig) { - if (!templateConfig['element']) { - throwError(componentName, 'Unknown template value: ' + templateConfig); + if (templateConfig) { + if (!templateConfig['element']) { + throwError(componentName, 'Unknown template value: ' + templateConfig); + } + // Element ID - find it, then copy its child nodes + var element = templateConfig['element']; + var elemInstance = document.getElementById(element); + if (!elemInstance) { + throwError(componentName, 'Cannot find element with ID ' + element); + } + if (!elemInstance.matches('TEMPLATE')) { + throwError(componentName, 'Template Source Element not a