From d81d8a929815016e0b4e2ad2a2cdfd671d4c9330 Mon Sep 17 00:00:00 2001 From: Lars Jung Date: Sun, 26 Jul 2020 22:45:36 +0200 Subject: [PATCH] Update. --- CHANGELOG.md | 1 + src/_h5ai/public/index.php | 2 +- src/_h5ai/public/js/lib/server.js | 4 +- src/_h5ai/public/js/lib/util/dom.js | 44 +++++++------- src/_h5ai/public/js/lib/util/index.js | 2 +- src/_h5ai/public/js/lib/util/misc.js | 10 ++-- src/_h5ai/public/js/lib/util/naturalCmp.js | 63 --------------------- src/_h5ai/public/js/lib/util/natural_cmp.js | 63 +++++++++++++++++++++ src/_h5ai/public/js/lib/view/base.js | 12 ++-- src/_h5ai/public/js/pre.js | 20 +++---- 10 files changed, 111 insertions(+), 110 deletions(-) delete mode 100644 src/_h5ai/public/js/lib/util/naturalCmp.js create mode 100644 src/_h5ai/public/js/lib/util/natural_cmp.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f2a5f99..5ca44ef8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog +* now require PHP 7.0.0+ * fix archive-single-item problem * add header/footer search stop condition * update languages (`id`, `it`, `pt-br`, `pt-pt`) diff --git a/src/_h5ai/public/index.php b/src/_h5ai/public/index.php index 96731e9b..e6552905 100644 --- a/src/_h5ai/public/index.php +++ b/src/_h5ai/public/index.php @@ -1,7 +1,7 @@ { return new Promise(resolve => { const xhr = new XHR(); - const onReadyStateChange = () => { + const on_ready_state_change = () => { if (xhr.readyState === XHR.DONE) { try { resolve(JSON.parse(xhr.responseText)); @@ -15,7 +15,7 @@ const request = data => { }; xhr.open('POST', '?', true); - xhr.onreadystatechange = onReadyStateChange; + xhr.onreadystatechange = on_ready_state_change; xhr.setRequestHeader('Content-Type', 'application/json;charset=utf-8'); xhr.send(JSON.stringify(data)); }); diff --git a/src/_h5ai/public/js/lib/util/dom.js b/src/_h5ai/public/js/lib/util/dom.js index ff57b243..2b8f3add 100644 --- a/src/_h5ai/public/js/lib/util/dom.js +++ b/src/_h5ai/public/js/lib/util/dom.js @@ -3,7 +3,7 @@ const {each, filter, hasLength, is, isStr, map, isInstanceOf, toArray} = require const win = global.window; const doc = win.document; -const parseHtml = (() => { +const parse_html = (() => { const create = name => doc.createElement(name); const rules = [ [/^ { }; })(); -const queryAll = (selector, context = doc) => { +const query_all = (selector, context = doc) => { try { return toArray(context.querySelectorAll(selector)); } catch (err) { @@ -40,27 +40,27 @@ const queryAll = (selector, context = doc) => { } }; -const isElement = x => isInstanceOf(x, win.Element); -const isDocument = x => isInstanceOf(x, win.Document); -const isWindow = x => is(x) && x.window === x && isDocument(x.document); -const isElDocWin = x => isElement(x) || isDocument(x) || isWindow(x); +const is_el = x => isInstanceOf(x, win.Element); +const is_doc = x => isInstanceOf(x, win.Document); +const is_win = x => is(x) && x.window === x && is_doc(x.document); +const is_el_doc_win = x => is_el(x) || is_doc(x) || is_win(x); -const addListener = (el, type, fn) => el.addEventListener(type, fn); -const removeListener = (el, type, fn) => el.removeEventListener(type, fn); +const add_listener = (el, type, fn) => el.addEventListener(type, fn); +const remove_listener = (el, type, fn) => el.removeEventListener(type, fn); -const readyPromise = new Promise(resolve => { +const ready_promise = new Promise(resolve => { if ((/^(i|c|loade)/).test(doc.readyState)) { resolve(); } else { - addListener(doc, 'DOMContentLoaded', () => resolve()); + add_listener(doc, 'DOMContentLoaded', () => resolve()); } }); -const awaitReady = () => readyPromise; +const await_ready = () => ready_promise; -const loadPromise = new Promise(resolve => { - addListener(win, 'load', () => resolve()); +const load_promise = new Promise(resolve => { + add_listener(win, 'load', () => resolve()); }); -const awaitLoad = () => loadPromise; +const await_load = () => load_promise; const dom = arg => { if (isInstanceOf(arg, dom)) { @@ -70,13 +70,13 @@ const dom = arg => { let els; if (isStr(arg)) { arg = arg.trim(); - els = arg[0] === '<' ? parseHtml(arg) : queryAll(arg); - } else if (isElDocWin(arg)) { + els = arg[0] === '<' ? parse_html(arg) : query_all(arg); + } else if (is_el_doc_win(arg)) { els = [arg]; } else { els = hasLength(arg) ? arg : [arg]; } - els = filter(els, isElDocWin); + els = filter(els, is_el_doc_win); return Object.assign(Object.create(dom.prototype), els, {length: els.length}); }; @@ -94,15 +94,15 @@ dom.prototype = { }, find(selector) { - return dom([].concat(...this.map(el => queryAll(selector, el)))); + return dom([].concat(...this.map(el => query_all(selector, el)))); }, on(type, fn) { - return this.each(el => addListener(el, type, fn)); + return this.each(el => add_listener(el, type, fn)); }, off(type, fn) { - return this.each(el => removeListener(el, type, fn)); + return this.each(el => remove_listener(el, type, fn)); }, attr(key, value) { @@ -271,7 +271,7 @@ dom.prototype = { }; module.exports = { - awaitReady, - awaitLoad, + awaitReady: await_ready, + awaitLoad: await_load, dom }; diff --git a/src/_h5ai/public/js/lib/util/index.js b/src/_h5ai/public/js/lib/util/index.js index 90634b27..ed1d4460 100644 --- a/src/_h5ai/public/js/lib/util/index.js +++ b/src/_h5ai/public/js/lib/util/index.js @@ -1,6 +1,6 @@ module.exports = Object.assign({}, require('./lo'), require('./dom'), - require('./naturalCmp'), + require('./natural_cmp'), require('./misc') ); diff --git a/src/_h5ai/public/js/lib/util/misc.js b/src/_h5ai/public/js/lib/util/misc.js index 26fadf9a..b63b3411 100644 --- a/src/_h5ai/public/js/lib/util/misc.js +++ b/src/_h5ai/public/js/lib/util/misc.js @@ -1,10 +1,10 @@ -const escapePattern = sequence => { +const esc_pattern = sequence => { return sequence.replace(/[\-\[\]{}()*+?.,\\$\^|#\s]/g, '\\$&'); }; -const parsePattern = (sequence, advanced) => { +const parse_pattern = (sequence, advanced) => { if (!advanced) { - return escapePattern(sequence); + return esc_pattern(sequence); } if (sequence.substr(0, 3) === 're:') { @@ -12,10 +12,10 @@ const parsePattern = (sequence, advanced) => { } return sequence.trim().split(/\s+/).map(part => { - return part.split('').map(char => escapePattern(char)).join('.*?'); + return part.split('').map(char => esc_pattern(char)).join('.*?'); }).join('|'); }; module.exports = { - parsePattern + parsePattern: parse_pattern }; diff --git a/src/_h5ai/public/js/lib/util/naturalCmp.js b/src/_h5ai/public/js/lib/util/naturalCmp.js deleted file mode 100644 index 888e23a8..00000000 --- a/src/_h5ai/public/js/lib/util/naturalCmp.js +++ /dev/null @@ -1,63 +0,0 @@ -// Natural Sort algorithm for Javascript - Version 0.7 - Released under MIT license -// Author: Jim Palmer (based on chunking idea from Dave Koelle) - -// Modified to make it work with h5ai - -const reToken = /(^([+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?)?$|^0x[0-9a-f]+$|\d+)/gi; -const reDate = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/; -const reHex = /^0x[0-9a-f]+$/i; -const reLeadingZero = /^0/; - -/* eslint-disable complexity */ -const naturalCmp = (a, b) => { - // convert all to strings strip whitespace - const x = String(a).trim(); - const y = String(b).trim(); - - // chunk/tokenize - const xTokens = x.replace(reToken, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'); - const yTokens = y.replace(reToken, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'); - - // first try and sort Hex codes or Dates - const xDate = parseInt(x.match(reHex), 16) || xTokens.length !== 1 && x.match(reDate) && Date.parse(x); - const yDate = parseInt(y.match(reHex), 16) || xDate && y.match(reDate) && Date.parse(y) || null; - if (yDate) { - if (xDate < yDate) { - return -1; - } - if (xDate > yDate) { - return 1; - } - } - - // natural sorting through split numeric strings and default strings - for (let idx = 0, len = Math.max(xTokens.length, yTokens.length); idx < len; idx += 1) { - // find floats not starting with '0', string or 0 if not defined (Clint Priest) - let xToken = !(xTokens[idx] || '').match(reLeadingZero) && parseFloat(xTokens[idx]) || xTokens[idx] || 0; - let yToken = !(yTokens[idx] || '').match(reLeadingZero) && parseFloat(yTokens[idx]) || yTokens[idx] || 0; - - // handle numeric vs string comparison - number < string - (Kyle Adams) - if (isNaN(xToken) !== isNaN(yToken)) { - return isNaN(xToken) ? 1 : -1; - } - - // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2' - if (typeof xToken !== typeof yToken) { - xToken = String(xToken); - yToken = String(yToken); - } - - if (xToken < yToken) { - return -1; - } - if (xToken > yToken) { - return 1; - } - } - return 0; -}; -/* eslint-enable */ - -module.exports = { - naturalCmp -}; diff --git a/src/_h5ai/public/js/lib/util/natural_cmp.js b/src/_h5ai/public/js/lib/util/natural_cmp.js new file mode 100644 index 00000000..d656f70a --- /dev/null +++ b/src/_h5ai/public/js/lib/util/natural_cmp.js @@ -0,0 +1,63 @@ +// Natural Sort algorithm for Javascript - Version 0.7 - Released under MIT license +// Author: Jim Palmer (based on chunking idea from Dave Koelle) + +// Modified to make it work with h5ai + +const RE_TOKEN = /(^([+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?)?$|^0x[0-9a-f]+$|\d+)/gi; +const RE_DATE = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/; +const RE_HEX = /^0x[0-9a-f]+$/i; +const RE_LEADING_ZERO = /^0/; + +/* eslint-disable complexity */ +const natural_cmp = (a, b) => { + // convert all to strings strip whitespace + const x = String(a).trim(); + const y = String(b).trim(); + + // chunk/tokenize + const x_toks = x.replace(RE_TOKEN, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'); + const y_toks = y.replace(RE_TOKEN, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'); + + // first try and sort Hex codes or Dates + const x_date = parseInt(x.match(RE_HEX), 16) || x_toks.length !== 1 && x.match(RE_DATE) && Date.parse(x); + const y_date = parseInt(y.match(RE_HEX), 16) || x_date && y.match(RE_DATE) && Date.parse(y) || null; + if (y_date) { + if (x_date < y_date) { + return -1; + } + if (x_date > y_date) { + return 1; + } + } + + // natural sorting through split numeric strings and default strings + for (let idx = 0, len = Math.max(x_toks.length, y_toks.length); idx < len; idx += 1) { + // find floats not starting with '0', string or 0 if not defined (Clint Priest) + let x_tok = !(x_toks[idx] || '').match(RE_LEADING_ZERO) && parseFloat(x_toks[idx]) || x_toks[idx] || 0; + let y_tok = !(y_toks[idx] || '').match(RE_LEADING_ZERO) && parseFloat(y_toks[idx]) || y_toks[idx] || 0; + + // handle numeric vs string comparison - number < string - (Kyle Adams) + if (isNaN(x_tok) !== isNaN(y_tok)) { + return isNaN(x_tok) ? 1 : -1; + } + + // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2' + if (typeof x_tok !== typeof y_tok) { + x_tok = String(x_tok); + y_tok = String(y_tok); + } + + if (x_tok < y_tok) { + return -1; + } + if (x_tok > y_tok) { + return 1; + } + } + return 0; +}; +/* eslint-enable */ + +module.exports = { + naturalCmp: natural_cmp +}; diff --git a/src/_h5ai/public/js/lib/view/base.js b/src/_h5ai/public/js/lib/view/base.js index 3f51c397..ffabe583 100644 --- a/src/_h5ai/public/js/lib/view/base.js +++ b/src/_h5ai/public/js/lib/view/base.js @@ -1,7 +1,7 @@ const {dom} = require('../util'); -const rootSelector = 'body'; -const topbarTpl = +const SEL_ROOT = 'body'; +const TPL_TOPBAR = `
@@ -10,17 +10,17 @@ const topbarTpl =
by h5ai
`; -const mainrowTpl = +const TPL_MAINROW = `
`; const init = () => { - const $root = dom(rootSelector) + const $root = dom(SEL_ROOT) .attr('id', 'root') .clr() - .app(topbarTpl) - .app(mainrowTpl); + .app(TPL_TOPBAR) + .app(TPL_MAINROW); return { $root, diff --git a/src/_h5ai/public/js/pre.js b/src/_h5ai/public/js/pre.js index 4ee56312..46defb02 100644 --- a/src/_h5ai/public/js/pre.js +++ b/src/_h5ai/public/js/pre.js @@ -4,25 +4,25 @@ throw new Error('no-window'); } - var noBrowser = 'no-browser'; - var docEl = win.document.documentElement; - docEl.className = ''; + var no_browser = 'no-browser'; + var doc_el = win.document.documentElement; + doc_el.className = ''; function assert(msg, expr) { if (!expr) { - docEl.className = noBrowser; - throw new Error(noBrowser + ': ' + msg); + doc_el.className = no_browser; + throw new Error(no_browser + ': ' + msg); } } - function isFn(x) { + function is_fn(x) { return typeof x === 'function'; } - assert('console', win.console && isFn(win.console.log)); - assert('assign', win.Object && isFn(win.Object.assign)); - assert('promise', isFn(win.Promise)); - // assert('xhr', isFn(win.XMLHttpRequest)); // is object in safari + assert('console', win.console && is_fn(win.console.log)); + assert('assign', win.Object && is_fn(win.Object.assign)); + assert('promise', is_fn(win.Promise)); + // assert('xhr', is_fn(win.XMLHttpRequest)); // is object in safari assert('xhr', win.XMLHttpRequest); }(this)); /* eslint-enable */