diff --git a/.eslintrc b/.eslintrc index 03ecbc1e..3a40be12 100644 --- a/.eslintrc +++ b/.eslintrc @@ -5,29 +5,8 @@ es6: true node: true - ecmaFeatures: - arrowFunctions: true - binaryLiterals: true - blockBindings: true - classes: false - defaultParams: true - destructuring: true - forOf: true - generators: true - globalReturn: true - jsx: false - modules: true - objectLiteralComputedProperties: true - objectLiteralDuplicateProperties: true - objectLiteralShorthandMethods: true - objectLiteralShorthandProperties: true - octalLiterals: true - regexUFlag: true - regexYFlag: true - spread: true - superInFunctions: false - templateStrings: true - unicodeCodePointEscapes: true + parserOptions: + ecmaVersion: 6 rules: array-bracket-spacing: [2, never] @@ -179,7 +158,7 @@ prefer-const: 1 prefer-reflect: 1 prefer-spread: 2 - prefer-template: 0 ### + prefer-template: 0 quote-props: [2, as-needed] quotes: [2, single, avoid-escape] radix: 2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 0802caee..658d8617 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Changelog +* add options to filter/search ignore case * replace PHP `getenv` calls with `$_SERVER` lookups * adds `view.fallbackMode` option to generally serve only fallback mode * serves fallback mode for text browsers (`curl`, `links`, `lynx`, `w3m`) @@ -15,7 +16,7 @@ * updates `jQuery` to 2.2.4 * updates `jquery-qrcode` to 0.14.0 * updates `lodash` to 4.13.1 (removes `contains`) -* updates `modulejs` to 1.14.0 +* removes `modulejs` ## v0.28.0 - *2015-12-19* diff --git a/ghu.js b/ghu.js index 198cb02f..994e2156 100644 --- a/ghu.js +++ b/ghu.js @@ -1,7 +1,7 @@ const {resolve, join} = require('path'); const { ghu, autoprefixer, cssmin, each, ife, includeit, jszip, less, mapfn, - newerThan, pug, read, remove, run, uglify, watch, wrap, write + newerThan, pug, read, remove, run, uglify, watch, webpack, wrap, write } = require('ghu'); const ROOT = resolve(__dirname); @@ -49,8 +49,27 @@ ghu.task('lint', 'lint all JavaScript files with eslint', () => { }); ghu.task('build:scripts', runtime => { - return read(`${SRC}/_h5ai/public/js/*.js`) + const webpackConfig = { + output: {}, + module: { + loaders: [ + { + include: [SRC], + loader: 'babel', + query: { + presets: ['es2015'], + cacheDirectory: true + } + } + ], + presets: ['es2015'] + } + }; + + return read(`${SRC}/_h5ai/public/js/scripts.js`) .then(newerThan(mapper, `${SRC}/_h5ai/public/js/**`)) + .then(webpack(webpackConfig, {showStats: true})) + .then(wrap('\n\n// @include "vendor/*"\n\n')) .then(includeit()) .then(ife(() => runtime.args.production, uglify())) .then(wrap(runtime.commentJs)) diff --git a/package.json b/package.json index fc04fea0..f1e02782 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,8 @@ "build": "node ghu release" }, "devDependencies": { + "babel-loader": "6.2.4", + "babel-preset-es2015": "6.9.0", "eslint": "2.11.0", "ghu": "0.6.0" }, diff --git a/src/.eslintrc b/src/.eslintrc index f6c585b8..a7634f9f 100644 --- a/src/.eslintrc +++ b/src/.eslintrc @@ -1,43 +1,5 @@ --- - env: - es6: false - node: false - browser: true - mocha: false - - globals: - modulejs: false - - ecmaFeatures: - arrowFunctions: false - binaryLiterals: false - blockBindings: false - classes: false - defaultParams: false - destructuring: false - forOf: false - generators: false - globalReturn: false - jsx: false - modules: false - objectLiteralComputedProperties: false - objectLiteralDuplicateProperties: false - objectLiteralShorthandMethods: false - objectLiteralShorthandProperties: false - octalLiterals: false - regexUFlag: false - regexYFlag: false - spread: false - superInFunctions: false - templateStrings: false - unicodeCodePointEscapes: false - rules: - consistent-this: 0 - func-names: 0 max-params: [1, 10] - no-invalid-this: 0 - no-var: 0 - object-shorthand: 0 - prefer-arrow-callback: 0 + no-console: 1 prefer-reflect: 0 diff --git a/src/_h5ai/private/conf/options.json b/src/_h5ai/private/conf/options.json index 9f1c9dcd..ac7869fa 100644 --- a/src/_h5ai/private/conf/options.json +++ b/src/_h5ai/private/conf/options.json @@ -144,11 +144,13 @@ - advanced: boolean, use advanced pattern parsing - debounceTime: number, debounce wait time in milliseconds + - ignorecase: boolean, ignore case */ "filter": { - "enabled": false, + "enabled": true, "advanced": true, - "debounceTime": 100 + "debounceTime": 100, + "ignorecase": true }, /* @@ -311,11 +313,13 @@ - advanced: boolean, use advanced pattern parsing - debounceTime: number, debounce wait time in milliseconds + - ignorecase: boolean, ignore case */ "search": { "enabled": true, "advanced": true, - "debounceTime": 300 + "debounceTime": 300, + "ignorecase": true }, /* diff --git a/src/_h5ai/private/php/core/class-api.php b/src/_h5ai/private/php/core/class-api.php index 204f1a35..b882f072 100644 --- a/src/_h5ai/private/php/core/class-api.php +++ b/src/_h5ai/private/php/core/class-api.php @@ -45,7 +45,6 @@ class Api { foreach (['langs', 'options', 'types'] as $name) { if ($this->request->query_boolean($name, false)) { - $methodname = 'get_' . $name; $response[$name] = $this->context->$methodname(); } @@ -84,8 +83,9 @@ class Api { Util::json_fail(Util::ERR_DISABLED, 'search disabled', !$this->context->query_option('search.enabled', false)); $href = $this->request->query('search.href'); $pattern = $this->request->query('search.pattern'); + $ignorecase = $this->request->query_boolean('search.ignorecase', false); $search = new Search($this->context); - $response['search'] = $search->get_items($href, $pattern); + $response['search'] = $search->get_items($href, $pattern, $ignorecase); } if ($this->request->query('thumbs', false)) { diff --git a/src/_h5ai/private/php/ext/class-search.php b/src/_h5ai/private/php/ext/class-search.php index 0477ac05..124954d0 100644 --- a/src/_h5ai/private/php/ext/class-search.php +++ b/src/_h5ai/private/php/ext/class-search.php @@ -7,10 +7,13 @@ class Search { $this->context = $context; } - public function get_paths($root, $pattern = null) { + public function get_paths($root, $pattern = null, $ignorecase = false) { $paths = []; if ($pattern && $this->context->is_managed_path($root)) { $re = Util::wrap_pattern($pattern); + if ($ignorecase) { + $re .= 'i'; + } $names = $this->context->read_dir($root); foreach ($names as $name) { $path = $root . '/' . $name; @@ -18,17 +21,17 @@ class Search { $paths[] = $path; } if (@is_dir($path)) { - $paths = array_merge($paths, $this->get_paths($path, $pattern)); + $paths = array_merge($paths, $this->get_paths($path, $pattern, $ignorecase)); } } } return $paths; } - public function get_items($href, $pattern = null) { + public function get_items($href, $pattern = null, $ignorecase = false) { $cache = []; $root = $this->context->to_path($href); - $paths = $this->get_paths($root, $pattern); + $paths = $this->get_paths($root, $pattern, $ignorecase); $items = array_map(function ($path) { return Item::get($this->context, $path, $cache)->to_json_object(); }, $paths); diff --git a/src/_h5ai/public/js/lib/boot.js b/src/_h5ai/public/js/lib/boot.js deleted file mode 100644 index 5666bd1b..00000000 --- a/src/_h5ai/public/js/lib/boot.js +++ /dev/null @@ -1,25 +0,0 @@ -modulejs.define('boot', ['$', 'core/server'], function ($, server) { - var module = $('script[data-module]').data('module'); - var data = { - action: 'get', - setup: true, - options: true, - types: true - }; - - if (module === 'index') { - data.theme = true; - data.langs = true; - } else if (module === 'info') { - data.refresh = true; - } else { - return; - } - - server.request(data, function (config) { - modulejs.define('config', config); - $(function () { - modulejs.require('main/' + module); - }); - }); -}); diff --git a/src/_h5ai/public/js/lib/config.js b/src/_h5ai/public/js/lib/config.js new file mode 100644 index 00000000..a624c613 --- /dev/null +++ b/src/_h5ai/public/js/lib/config.js @@ -0,0 +1,10 @@ +const {request} = require('./core/server'); + +const config = module.exports = { + _update: data => { + return request(data).then(newConfig => { + Object.assign(config, newConfig); + return config; + }); + } +}; diff --git a/src/_h5ai/public/js/lib/core/event.js b/src/_h5ai/public/js/lib/core/event.js index 046e8da1..6dc67b0b 100644 --- a/src/_h5ai/public/js/lib/core/event.js +++ b/src/_h5ai/public/js/lib/core/event.js @@ -1,36 +1,33 @@ -modulejs.define('core/event', ['_'], function (_) { - var slice = Array.prototype.slice; - var subscriptions = {}; +const {_: lo} = require('../win'); - function sub(topic, callback) { - if (_.isString(topic) && _.isFunction(callback)) { - if (!subscriptions[topic]) { - subscriptions[topic] = []; - } - subscriptions[topic].push(callback); +const subscriptions = {}; + +function sub(topic, listener) { + if (lo.isString(topic) && lo.isFunction(listener)) { + if (!subscriptions[topic]) { + subscriptions[topic] = []; } + subscriptions[topic].push(listener); } +} - function unsub(topic, callback) { - if (_.isString(topic) && _.isFunction(callback) && subscriptions[topic]) { - subscriptions[topic] = _.without(subscriptions[topic], callback); - } +function unsub(topic, listener) { + if (lo.isString(topic) && lo.isFunction(listener) && subscriptions[topic]) { + subscriptions[topic] = lo.without(subscriptions[topic], listener); } +} - function pub(topic) { - var args = slice.call(arguments, 1); - - if (_.isString(topic) && subscriptions[topic]) { - _.each(subscriptions[topic], function (callback) { - callback.apply(topic, args); - }); - } +function pub(topic, ...args) { + // console.log(topic, args); + if (lo.isString(topic) && subscriptions[topic]) { + lo.each(subscriptions[topic], listener => { + listener.apply(topic, args); + }); } +} - - return { - sub: sub, - unsub: unsub, - pub: pub - }; -}); +module.exports = { + sub, + unsub, + pub +}; diff --git a/src/_h5ai/public/js/lib/core/format.js b/src/_h5ai/public/js/lib/core/format.js index 4290ae93..5eab78b4 100644 --- a/src/_h5ai/public/js/lib/core/format.js +++ b/src/_h5ai/public/js/lib/core/format.js @@ -1,95 +1,96 @@ -modulejs.define('core/format', ['_'], function (_) { - var decimalMetric = { - t: 1000.0, - k: 1000.0, - u: ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] +const {_: lo} = require('../win'); + +const decimalMetric = { + t: 1000.0, + k: 1000.0, + u: ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] +}; +const binaryMetric = { + t: 1024.0, + k: 1024.0, + u: ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'] +}; +let defaultMetric = decimalMetric; + +const datePatterns = [ + [/YYYY/, 'Y', 4], + [/YY/, 'Y', 2], + [/Y/, 'Y', 0], + [/MM/, 'M', 2], + [/M/, 'M', 0], + [/DD/, 'D', 2], + [/D/, 'D', 0], + [/HH/, 'H', 2], + [/H/, 'H', 0], + [/mm/, 'm', 2], + [/m/, 'm', 0], + [/ss/, 's', 2], + [/s/, 's', 0] +]; +let defaultDateFormat = 'YYYY-MM-DD HH:mm'; + + +function setDefaultMetric(useBinaryMetric) { + defaultMetric = useBinaryMetric ? binaryMetric : decimalMetric; +} + +function formatSize(size, metric) { + metric = metric || defaultMetric; + + if (!lo.isNumber(size) || size < 0) { + return ''; + } + + let i = 0; + const maxI = metric.u.length - 1; + + while (size >= metric.t && i < maxI) { + size /= metric.k; + i += 1; + } + return (i <= 1 ? Math.round(size) : size.toFixed(1)).toString() + ' ' + metric.u[i]; +} + +function setDefaultDateFormat(dateFormat) { + defaultDateFormat = dateFormat; +} + +function formatNumber(number, padding) { + let str = String(number); + if (padding) { + str = ('000' + str).substr(-padding); + } + return str; +} + +function formatDate(millis, format) { + if (!millis || !lo.isNumber(millis)) { + return ''; + } + + format = format || defaultDateFormat; + + const date = new Date(millis); + const d = { + Y: date.getFullYear(), + M: date.getMonth() + 1, + D: date.getDate(), + H: date.getHours(), + m: date.getMinutes(), + s: date.getSeconds() }; - var binaryMetric = { - t: 1024.0, - k: 1024.0, - u: ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'] - }; - var defaultMetric = decimalMetric; - var datePatterns = [ - [/YYYY/, 'Y', 4], - [/YY/, 'Y', 2], - [/Y/, 'Y', 0], - [/MM/, 'M', 2], - [/M/, 'M', 0], - [/DD/, 'D', 2], - [/D/, 'D', 0], - [/HH/, 'H', 2], - [/H/, 'H', 0], - [/mm/, 'm', 2], - [/m/, 'm', 0], - [/ss/, 's', 2], - [/s/, 's', 0] - ]; - var defaultDateFormat = 'YYYY-MM-DD HH:mm'; + + datePatterns.forEach(pattern => { + format = format.replace(pattern[0], formatNumber(d[pattern[1]], pattern[2])); + }); + + return format; +} - function setDefaultMetric(useBinaryMetric) { - defaultMetric = useBinaryMetric ? binaryMetric : decimalMetric; - } - - function formatSize(size, metric) { - metric = metric || defaultMetric; - - if (!_.isNumber(size) || size < 0) { - return ''; - } - - var i = 0; - var maxI = metric.u.length - 1; - - while (size >= metric.t && i < maxI) { - size /= metric.k; - i += 1; - } - return (i <= 1 ? Math.round(size) : size.toFixed(1)).toString() + ' ' + metric.u[i]; - } - - function setDefaultDateFormat(dateFormat) { - defaultDateFormat = dateFormat; - } - - function formatNumber(number, padding) { - var str = String(number); - if (padding) { - str = ('000' + str).substr(-padding); - } - return str; - } - - function formatDate(millis, format) { - if (!millis || !_.isNumber(millis)) { - return ''; - } - - format = format || defaultDateFormat; - - var date = new Date(millis); - var d = { - Y: date.getFullYear(), - M: date.getMonth() + 1, - D: date.getDate(), - H: date.getHours(), - m: date.getMinutes(), - s: date.getSeconds() - }; - - datePatterns.forEach(function (pattern) { - format = format.replace(pattern[0], formatNumber(d[pattern[1]], pattern[2])); - }); - - return format; - } - - - return { - setDefaultMetric: setDefaultMetric, - formatSize: formatSize, - setDefaultDateFormat: setDefaultDateFormat, - formatDate: formatDate - }; -}); +module.exports = { + setDefaultMetric, + formatSize, + setDefaultDateFormat, + formatDate +}; diff --git a/src/_h5ai/public/js/lib/core/langs.js b/src/_h5ai/public/js/lib/core/langs.js index 84193cf1..b78bfcd5 100644 --- a/src/_h5ai/public/js/lib/core/langs.js +++ b/src/_h5ai/public/js/lib/core/langs.js @@ -1,3 +1,2 @@ -modulejs.define('core/langs', ['_', 'config'], function (_, config) { - return _.extend({}, config.langs); -}); +const config = require('../config'); +module.exports = Object.assign({}, config.langs); diff --git a/src/_h5ai/public/js/lib/core/location.js b/src/_h5ai/public/js/lib/core/location.js index 1a9d7452..779ae871 100644 --- a/src/_h5ai/public/js/lib/core/location.js +++ b/src/_h5ai/public/js/lib/core/location.js @@ -1,181 +1,191 @@ -modulejs.define('core/location', ['_', 'core/event', 'core/modernizr', 'core/settings', 'view/notification'], function (_, event, modernizr, allsettings, notification) { - var settings = _.extend({ - fastBrowsing: true, - unmanagedInNewWindow: true - }, allsettings.view); - var doc = document; - var history = settings.fastBrowsing && modernizr.history ? window.history : null; - var reUriToPathname = /^.*:\/\/[^\/]*|[^\/]*$/g; - var absHref = null; - var reForceEncoding = [ - [/\/+/g, '/'], - [/ /g, '%20'], - [/!/g, '%21'], - [/#/g, '%23'], - [/\$/g, '%24'], - [/&/g, '%26'], - [/'/g, '%27'], - [/\(/g, '%28'], - [/\)/g, '%29'], - [/\*/g, '%2A'], - [/\+/g, '%2B'], - [/\,/g, '%2C'], - [/:/g, '%3A'], - [/;/g, '%3B'], - [/\=/g, '%3D'], - [/\?/g, '%3F'], - [/@/g, '%40'], - [/\[/g, '%5B'], - [/\]/g, '%5D'] - ]; +const {window: win, document: doc, _: lo} = require('../win'); +const {request} = require('./server'); +const allsettings = require('./settings'); +const modernizr = require('./modernizr'); +const event = require('./event'); - function forceEncoding(href) { - return reForceEncoding.reduce(function (nuHref, data) { - return nuHref.replace(data[0], data[1]); - }, href); +const notification = require('../view/notification'); + + +const settings = lo.extend({ + fastBrowsing: true, + unmanagedInNewWindow: true +}, allsettings.view); +const history = settings.fastBrowsing && modernizr.history ? win.history : null; +const reUriToPathname = /^.*:\/\/[^\/]*|[^\/]*$/g; +const reForceEncoding = [ + [/\/+/g, '/'], + [/ /g, '%20'], + [/!/g, '%21'], + [/#/g, '%23'], + [/\$/g, '%24'], + [/&/g, '%26'], + [/'/g, '%27'], + [/\(/g, '%28'], + [/\)/g, '%29'], + [/\*/g, '%2A'], + [/\+/g, '%2B'], + [/\,/g, '%2C'], + [/:/g, '%3A'], + [/;/g, '%3B'], + [/\=/g, '%3D'], + [/\?/g, '%3F'], + [/@/g, '%40'], + [/\[/g, '%5B'], + [/\]/g, '%5D'] +]; + + +let absHref = null; + + +function forceEncoding(href) { + return reForceEncoding.reduce((nuHref, data) => { + return nuHref.replace(data[0], data[1]); + }, href); +} + +function uriToPathname(uri) { + return uri.replace(reUriToPathname, ''); +} + +const hrefsAreDecoded = (() => { + const testpathname = '/a b'; + const a = doc.createElement('a'); + + a.href = testpathname; + return uriToPathname(a.href) === testpathname; +})(); + +function encodedHref(href) { + const a = doc.createElement('a'); + let location; + + a.href = href; + location = uriToPathname(a.href); + + if (hrefsAreDecoded) { + location = encodeURIComponent(location).replace(/%2F/ig, '/'); } - function uriToPathname(uri) { - return uri.replace(reUriToPathname, ''); - } + return forceEncoding(location); +} - var hrefsAreDecoded = (function () { - var testpathname = '/a b'; - var a = doc.createElement('a'); +function getDomain() { + return doc.domain; +} - a.href = testpathname; - return uriToPathname(a.href) === testpathname; - }()); +function getAbsHref() { + return absHref; +} - function encodedHref(href) { - var a = doc.createElement('a'); - var location; +function getItem() { + const Item = require('../model/item'); + return Item.get(absHref); +} - a.href = href; - location = uriToPathname(a.href); +function load(callback) { + request({action: 'get', items: {href: absHref, what: 1}}).then(json => { + const Item = require('../model/item'); + const item = Item.get(absHref); - if (hrefsAreDecoded) { - location = encodeURIComponent(location).replace(/%2F/ig, '/'); - } + if (json) { + const found = {}; - return forceEncoding(location); - } + lo.each(json.items, jsonItem => { + const e = Item.get(jsonItem); + found[e.absHref] = true; + }); - function getDomain() { - return doc.domain; - } - - function getAbsHref() { - return absHref; - } - - function getItem() { - return modulejs.require('model/item').get(absHref); - } - - function load(callback) { - modulejs.require('core/server').request({action: 'get', items: {href: absHref, what: 1}}, function (json) { - var Item = modulejs.require('model/item'); - var item = Item.get(absHref); - - if (json) { - var found = {}; - - _.each(json.items, function (jsonItem) { - var e = Item.get(jsonItem); - found[e.absHref] = true; - }); - - _.each(item.content, function (e) { - if (!found[e.absHref]) { - Item.remove(e.absHref); - } - }); - } - if (_.isFunction(callback)) { - callback(item); - } - }); - } - - function refresh() { - var item = getItem(); - var oldItems = _.values(item.content); - - event.pub('location.beforeRefresh'); - - load(function () { - var newItems = _.values(item.content); - var added = _.difference(newItems, oldItems); - var removed = _.difference(oldItems, newItems); - - event.pub('location.refreshed', item, added, removed); - }); - } - - function setLocation(newAbsHref, keepBrowserUrl) { - event.pub('location.beforeChange'); - - newAbsHref = encodedHref(newAbsHref); - - if (absHref !== newAbsHref) { - absHref = newAbsHref; - - if (history) { - if (keepBrowserUrl) { - history.replaceState({absHref: absHref}, '', absHref); - } else { - history.pushState({absHref: absHref}, '', absHref); + lo.each(item.content, e => { + if (!found[e.absHref]) { + Item.remove(e.absHref); } + }); + } + if (lo.isFunction(callback)) { + callback(item); + } + }); +} + +function refresh() { + const item = getItem(); + const oldItems = lo.values(item.content); + + event.pub('location.beforeRefresh'); + + load(() => { + const newItems = lo.values(item.content); + const added = lo.difference(newItems, oldItems); + const removed = lo.difference(oldItems, newItems); + + event.pub('location.refreshed', item, added, removed); + }); +} + +function setLocation(newAbsHref, keepBrowserUrl) { + event.pub('location.beforeChange'); + + newAbsHref = encodedHref(newAbsHref); + + if (absHref !== newAbsHref) { + absHref = newAbsHref; + + if (history) { + if (keepBrowserUrl) { + history.replaceState({absHref}, '', absHref); + } else { + history.pushState({absHref}, '', absHref); } } + } - var item = getItem(); - if (item.isLoaded) { + const item = getItem(); + if (item.isLoaded) { + event.pub('location.changed', item); + refresh(); + } else { + notification.set('loading...'); + load(() => { + item.isLoaded = true; + notification.set(); event.pub('location.changed', item); - refresh(); - } else { - notification.set('loading...'); - load(function () { - item.isLoaded = true; - notification.set(); - event.pub('location.changed', item); - }); - } + }); + } +} + +function setLink($el, item) { + $el.attr('href', item.absHref); + + if (history && item.isFolder() && item.isManaged) { + $el.on('click', () => { + setLocation(item.absHref); + return false; + }); } - function setLink($el, item) { - $el.attr('href', item.absHref); - - if (history && item.isFolder() && item.isManaged) { - $el.on('click', function () { - setLocation(item.absHref); - return false; - }); - } - - if (settings.unmanagedInNewWindow && !item.isManaged) { - $el.attr('target', '_blank'); - } + if (settings.unmanagedInNewWindow && !item.isManaged) { + $el.attr('target', '_blank'); } +} - function onPopState(ev) { - if (ev.state && ev.state.absHref) { - setLocation(ev.state.absHref, true); - } +function onPopState(ev) { + if (ev.state && ev.state.absHref) { + setLocation(ev.state.absHref, true); } +} - window.onpopstate = history ? onPopState : null; +win.onpopstate = history ? onPopState : null; - return { - forceEncoding: forceEncoding, - getDomain: getDomain, - getAbsHref: getAbsHref, - getItem: getItem, - setLocation: setLocation, - refresh: refresh, - setLink: setLink - }; -}); +module.exports = { + forceEncoding, + getDomain, + getAbsHref, + getItem, + setLocation, + refresh, + setLink +}; diff --git a/src/_h5ai/public/js/lib/core/modernizr.js b/src/_h5ai/public/js/lib/core/modernizr.js index c68e3c21..abbc14b2 100644 --- a/src/_h5ai/public/js/lib/core/modernizr.js +++ b/src/_h5ai/public/js/lib/core/modernizr.js @@ -1,25 +1,25 @@ -modulejs.define('core/modernizr', function () { - var hasCanvas = (function () { - var elem = document.createElement('canvas'); - return Boolean(elem.getContext && elem.getContext('2d')); - }()); +const win = require('../win'); - var hasHistory = Boolean(window.history && history.pushState); +const hasCanvas = (() => { + const elem = win.document.createElement('canvas'); + return !!(elem.getContext && elem.getContext('2d')); +})(); - var hasLocalStorage = (function () { - var key = '#test#'; - try { - localStorage.setItem(key, key); - localStorage.removeItem(key); - return true; - } catch (e) { - return false; - } - }()); +const hasHistory = !!(win.history && win.history.pushState); - return { - canvas: hasCanvas, - history: hasHistory, - localstorage: hasLocalStorage - }; -}); +const hasLocalStorage = (() => { + const key = '#test#'; + try { + win.localStorage.setItem(key, key); + win.localStorage.removeItem(key); + return true; + } catch (e) { + return false; + } +})(); + +module.exports = { + canvas: hasCanvas, + history: hasHistory, + localstorage: hasLocalStorage +}; diff --git a/src/_h5ai/public/js/lib/core/resource.js b/src/_h5ai/public/js/lib/core/resource.js index b7723628..785d5719 100644 --- a/src/_h5ai/public/js/lib/core/resource.js +++ b/src/_h5ai/public/js/lib/core/resource.js @@ -1,37 +1,39 @@ -modulejs.define('core/resource', ['_', 'config', 'core/settings'], function (_, config, settings) { - var imagesHref = settings.publicHref + 'images/'; - var uiHref = imagesHref + 'ui/'; - var themesHref = imagesHref + 'themes/'; - var defaultThemeHref = themesHref + 'default/'; - var defaultIcons = ['file', 'folder', 'folder-page', 'folder-parent', 'ar', 'aud', 'bin', 'img', 'txt', 'vid', 'x']; +const {_: lo} = require('../win'); +const config = require('../config'); +const settings = require('./settings'); + +const imagesHref = settings.publicHref + 'images/'; +const uiHref = imagesHref + 'ui/'; +const themesHref = imagesHref + 'themes/'; +const defaultThemeHref = themesHref + 'default/'; +const defaultIcons = ['file', 'folder', 'folder-page', 'folder-parent', 'ar', 'aud', 'bin', 'img', 'txt', 'vid', 'x']; - function image(id) { - return uiHref + id + '.svg'; +function image(id) { + return uiHref + id + '.svg'; +} + +function icon(id) { + const baseId = (id || '').split('-')[0]; + const href = config.theme[id] || config.theme[baseId]; + + if (href) { + return themesHref + href; } - function icon(id) { - var baseId = (id || '').split('-')[0]; - var href = config.theme[id] || config.theme[baseId]; - - if (href) { - return themesHref + href; - } - - if (_.includes(defaultIcons, id)) { - return defaultThemeHref + id + '.svg'; - } - - if (_.includes(defaultIcons, baseId)) { - return defaultThemeHref + baseId + '.svg'; - } - - return defaultThemeHref + 'file.svg'; + if (lo.includes(defaultIcons, id)) { + return defaultThemeHref + id + '.svg'; } + if (lo.includes(defaultIcons, baseId)) { + return defaultThemeHref + baseId + '.svg'; + } - return { - image: image, - icon: icon - }; -}); + return defaultThemeHref + 'file.svg'; +} + + +module.exports = { + image, + icon +}; diff --git a/src/_h5ai/public/js/lib/core/server.js b/src/_h5ai/public/js/lib/core/server.js index 59269469..473c9377 100644 --- a/src/_h5ai/public/js/lib/core/server.js +++ b/src/_h5ai/public/js/lib/core/server.js @@ -1,35 +1,32 @@ -modulejs.define('core/server', ['_', '$'], function (_, $) { - function request(data, callback) { - $.ajax({ +const {jQuery: jq, _: lo} = require('../win'); + +function request(data) { + return new Promise(resolve => { + jq.ajax({ url: '?', - data: data, + data, type: 'post', dataType: 'json' }) - .done(function (json) { - callback(json); - }) - .fail(function () { - callback(); - }); - } + .done(json => resolve(json)) + .fail(() => resolve()); + }); +} - function formRequest(data) { - var $form = $('
'); +function formRequest(data) { + const $form = jq(''); - _.each(data, function (val, key) { - $('') - .attr('name', key) - .attr('value', val) - .appendTo($form); - }); + lo.each(data, (val, key) => { + jq('') + .attr('name', key) + .attr('value', val) + .appendTo($form); + }); - $form.appendTo('body').submit().remove(); - } + $form.appendTo('body').submit().remove(); +} - - return { - request: request, - formRequest: formRequest - }; -}); +module.exports = { + request, + formRequest +}; diff --git a/src/_h5ai/public/js/lib/core/settings.js b/src/_h5ai/public/js/lib/core/settings.js index f459c472..f7f4cd28 100644 --- a/src/_h5ai/public/js/lib/core/settings.js +++ b/src/_h5ai/public/js/lib/core/settings.js @@ -1,6 +1,6 @@ -modulejs.define('core/settings', ['_', 'config'], function (_, config) { - return _.extend({}, config.options, { - publicHref: config.setup.PUBLIC_HREF, - rootHref: config.setup.ROOT_HREF - }); +const config = require('../config'); + +module.exports = Object.assign({}, config.options, { + publicHref: config.setup.PUBLIC_HREF, + rootHref: config.setup.ROOT_HREF }); diff --git a/src/_h5ai/public/js/lib/core/store.js b/src/_h5ai/public/js/lib/core/store.js index e9990869..74a5c551 100644 --- a/src/_h5ai/public/js/lib/core/store.js +++ b/src/_h5ai/public/js/lib/core/store.js @@ -1,32 +1,33 @@ -modulejs.define('core/store', ['core/modernizr'], function (modernizr) { - var store = modernizr.localstorage ? window.localStorage : {}; - var storekey = '_h5ai'; +const win = require('../win'); +const modernizr = require('./modernizr'); + +const store = modernizr.localstorage ? win.localStorage : {}; +const storekey = '_h5ai'; - function load() { - try { - return JSON.parse(store[storekey]); - } catch (e) {/* skip */} - return {}; - } +function load() { + try { + return JSON.parse(store[storekey]); + } catch (e) {/* skip */} + return {}; +} - function save(obj) { - store[storekey] = JSON.stringify(obj); - } +function save(obj) { + store[storekey] = JSON.stringify(obj); +} - function put(key, value) { - var obj = load(); - obj[key] = value; - save(obj); - } +function put(key, value) { + const obj = load(); + obj[key] = value; + save(obj); +} - function get(key) { - return load()[key]; - } +function get(key) { + return load()[key]; +} - return { - put: put, - get: get - }; -}); +module.exports = { + put, + get +}; diff --git a/src/_h5ai/public/js/lib/core/types.js b/src/_h5ai/public/js/lib/core/types.js index 53fdc7a6..88cf51dc 100644 --- a/src/_h5ai/public/js/lib/core/types.js +++ b/src/_h5ai/public/js/lib/core/types.js @@ -1,43 +1,44 @@ -modulejs.define('core/types', ['_', 'config'], function (_, config) { - var reEndsWithSlash = /\/$/; - var regexps = {}; +const {_: lo} = require('../win'); +const config = require('../config'); + +const reEndsWithSlash = /\/$/; +const regexps = {}; - function escapeRegExp(sequence) { - return sequence.replace(/[\-\[\]\/\{\}\(\)\+\?\.\\\^\$]/g, '\\$&'); - // return sequence.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'); +function escapeRegExp(sequence) { + return sequence.replace(/[\-\[\]\/\{\}\(\)\+\?\.\\\^\$]/g, '\\$&'); + // return sequence.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'); +} + +function parse(types) { + lo.each(types, (patterns, type) => { + const pattern = '^(' + lo.map(patterns, p => '(' + escapeRegExp(p).replace(/\*/g, '.*') + ')').join('|') + ')$'; + regexps[type] = new RegExp(pattern, 'i'); + }); +} + +function getType(sequence) { + if (reEndsWithSlash.test(sequence)) { + return 'folder'; } - function parse(types) { - _.each(types, function (patterns, type) { - var pattern = '^(' + _.map(patterns, function (p) { return '(' + escapeRegExp(p).replace(/\*/g, '.*') + ')'; }).join('|') + ')$'; - regexps[type] = new RegExp(pattern, 'i'); - }); - } + const slashidx = sequence.lastIndexOf('/'); + const name = slashidx >= 0 ? sequence.substr(slashidx + 1) : sequence; + let result; - function getType(sequence) { - if (reEndsWithSlash.test(sequence)) { - return 'folder'; + lo.each(regexps, (regexp, type) => { // eslint-disable-line consistent-return + if (regexps[type].test(name)) { + result = type; + return false; } + }); - var slashidx = sequence.lastIndexOf('/'); - var name = slashidx >= 0 ? sequence.substr(slashidx + 1) : sequence; - var result; - - _.each(regexps, function (regexp, type) { // eslint-disable-line consistent-return - if (regexps[type].test(name)) { - result = type; - return false; - } - }); - - return result ? result : 'file'; - } + return result ? result : 'file'; +} - parse(_.extend({}, config.types)); +parse(Object.assign({}, config.types)); - return { - getType: getType - }; -}); +module.exports = { + getType +}; diff --git a/src/_h5ai/public/js/lib/core/util.js b/src/_h5ai/public/js/lib/core/util.js index 772005a3..48682a03 100644 --- a/src/_h5ai/public/js/lib/core/util.js +++ b/src/_h5ai/public/js/lib/core/util.js @@ -1,93 +1,93 @@ -modulejs.define('core/util', ['_'], function (_) { - function regularCmpFn(val1, val2) { - if (val1 < val2) { +const {_: lo} = require('../win'); + +function regularCmpFn(val1, val2) { + if (val1 < val2) { + return -1; + } + if (val1 > val2) { + return 1; + } + return 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 +function naturalCmpFn(val1, val2) { + const re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi; + const sre = /(^[ ]*|[ ]*$)/g; + const dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/; + const hre = /^0x[0-9a-f]+$/i; + const ore = /^0/; + // convert all to strings strip whitespace + const x = String(val1).replace(sre, ''); + const y = String(val2).replace(sre, ''); + // chunk/tokenize + const xN = x.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'); + const yN = y.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'); + // numeric, hex or date detection + const xD = parseInt(x.match(hre), 10) || xN.length !== 1 && x.match(dre) && Date.parse(x); + const yD = parseInt(y.match(hre), 10) || xD && y.match(dre) && Date.parse(y) || null; + let oFxNcL; + let oFyNcL; + // first try and sort Hex codes or Dates + if (yD) { + if (xD < yD) { return -1; - } - if (val1 > val2) { + } else if (xD > yD) { return 1; } - return 0; + } + // natural sorting through split numeric strings and default strings + for (let cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc += 1) { + // find floats not starting with '0', string or 0 if not defined (Clint Priest) + oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0; + oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0; + // handle numeric vs string comparison - number < string - (Kyle Adams) + if (isNaN(oFxNcL) !== isNaN(oFyNcL)) { + return isNaN(oFxNcL) ? 1 : -1; + } else if (typeof oFxNcL !== typeof oFyNcL) { + // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2' + oFxNcL = String(oFxNcL); + oFxNcL = String(oFxNcL); + } + if (oFxNcL < oFyNcL) { + return -1; + } + if (oFxNcL > oFyNcL) { + return 1; + } + } + return 0; +} + +function escapePattern(sequence) { + return sequence.replace(/[\-\[\]{}()*+?.,\\$\^|#\s]/g, '\\$&'); +} + +function parsePattern(sequence, advanced) { + if (!advanced) { + return escapePattern(sequence); } - // 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 - function naturalCmpFn(val1, val2) { - var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi; - var sre = /(^[ ]*|[ ]*$)/g; - var dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/; - var hre = /^0x[0-9a-f]+$/i; - var ore = /^0/; - // convert all to strings strip whitespace - var x = String(val1).replace(sre, ''); - var y = String(val2).replace(sre, ''); - // chunk/tokenize - var xN = x.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'); - var yN = y.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'); - // numeric, hex or date detection - var xD = parseInt(x.match(hre), 10) || xN.length !== 1 && x.match(dre) && Date.parse(x); - var yD = parseInt(y.match(hre), 10) || xD && y.match(dre) && Date.parse(y) || null; - var oFxNcL; - var oFyNcL; - // first try and sort Hex codes or Dates - if (yD) { - if (xD < yD) { - return -1; - } else if (xD > yD) { - return 1; - } - } - // natural sorting through split numeric strings and default strings - for (var cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc += 1) { - // find floats not starting with '0', string or 0 if not defined (Clint Priest) - oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0; - oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0; - // handle numeric vs string comparison - number < string - (Kyle Adams) - if (isNaN(oFxNcL) !== isNaN(oFyNcL)) { - return isNaN(oFxNcL) ? 1 : -1; - } else if (typeof oFxNcL !== typeof oFyNcL) { - // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2' - oFxNcL = String(oFxNcL); - oFxNcL = String(oFxNcL); - } - if (oFxNcL < oFyNcL) { - return -1; - } - if (oFxNcL > oFyNcL) { - return 1; - } - } - return 0; + if (sequence.substr(0, 3) === 're:') { + return sequence.substr(3); } - function escapePattern(sequence) { - return sequence.replace(/[\-\[\]{}()*+?.,\\$\^|#\s]/g, '\\$&'); - } + sequence = lo.map(lo.trim(sequence).split(/\s+/), part => { + return lo.map(part.split(''), character => { + return escapePattern(character); + }).join('.*?'); + }).join('|'); - function parsePattern(sequence, advanced) { - if (!advanced) { - return escapePattern(sequence); - } - - if (sequence.substr(0, 3) === 're:') { - return sequence.substr(3); - } - - sequence = _.map(_.trim(sequence).split(/\s+/), function (part) { - return _.map(part.split(''), function (character) { - return escapePattern(character); - }).join('.*?'); - }).join('|'); - - return sequence; - } + return sequence; +} - return { - regularCmpFn: regularCmpFn, - naturalCmpFn: naturalCmpFn, - escapePattern: escapePattern, - parsePattern: parsePattern - }; -}); +module.exports = { + regularCmpFn, + naturalCmpFn, + escapePattern, + parsePattern +}; diff --git a/src/_h5ai/public/js/lib/ext/autorefresh.js b/src/_h5ai/public/js/lib/ext/autorefresh.js index 14da8242..b407e33b 100644 --- a/src/_h5ai/public/js/lib/ext/autorefresh.js +++ b/src/_h5ai/public/js/lib/ext/autorefresh.js @@ -1,37 +1,41 @@ -modulejs.define('ext/autorefresh', ['_', '$', 'core/event', 'core/location', 'core/settings'], function (_, $, event, location, allsettings) { - var settings = _.extend({ - enabled: false, - interval: 5000 - }, allsettings.autorefresh); - var timeoutId = null; +const {setTimeout} = require('../win'); +const event = require('../core/event'); +const location = require('../core/location'); +const allsettings = require('../core/settings'); - function heartbeat() { - location.refresh(); +const settings = Object.assign({ + enabled: false, + interval: 5000 +}, allsettings.autorefresh); +let timeoutId = null; + + +function heartbeat() { + location.refresh(); +} + +function before() { + clearTimeout(timeoutId); +} + +function after() { + clearTimeout(timeoutId); + timeoutId = setTimeout(heartbeat, settings.interval); +} + +function init() { + if (!settings.enabled) { + return; } - function before() { - clearTimeout(timeoutId); - } + settings.interval = Math.max(1000, settings.interval); - function after() { - clearTimeout(timeoutId); - timeoutId = setTimeout(heartbeat, settings.interval); - } - - function init() { - if (!settings.enabled) { - return; - } - - settings.interval = Math.max(1000, settings.interval); - - event.sub('location.beforeChange', before); - event.sub('location.beforeRefresh', before); - event.sub('location.changed', after); - event.sub('location.refreshed', after); - } + event.sub('location.beforeChange', before); + event.sub('location.beforeRefresh', before); + event.sub('location.changed', after); + event.sub('location.refreshed', after); +} - init(); -}); +init(); diff --git a/src/_h5ai/public/js/lib/ext/contextmenu.js b/src/_h5ai/public/js/lib/ext/contextmenu.js index c2b9bb9a..4173b5a7 100644 --- a/src/_h5ai/public/js/lib/ext/contextmenu.js +++ b/src/_h5ai/public/js/lib/ext/contextmenu.js @@ -1,163 +1,162 @@ -modulejs.define('ext/contextmenu', ['_', '$', 'core/resource', 'core/settings'], function (_, $, resource, allsettings) { - var settings = _.extend({ - enabled: false - }, allsettings.contextmenu); - var templateOverlay = '
'; - var templatePanel = '
    '; - var templateSep = '
  • '; - var templateEntry = '
  • '; - var templateLabel = '
  • '; +const {document: doc, jQuery: jq, _: lo} = require('../win'); +const resource = require('../core/resource'); +const allsettings = require('../core/settings'); + +const settings = lo.extend({ + enabled: false +}, allsettings.contextmenu); +const templateOverlay = '
    '; +const templatePanel = '
      '; +const templateSep = '
    • '; +const templateEntry = '
    • '; +const templateLabel = '
    • '; - function createOverlay(callback) { - var $overlay = $(templateOverlay); +function createOverlay(callback) { + const $overlay = jq(templateOverlay); - $overlay - .on('click contextmenu', function (ev) { - ev.stopPropagation(); - ev.preventDefault(); + $overlay + .on('click contextmenu', ev => { + ev.stopPropagation(); + ev.preventDefault(); - var cmId = $(ev.target).closest('.cm-entry').data('cm-id'); + const cmId = jq(ev.target).closest('.cm-entry').data('cm-id'); - if (ev.target === $overlay[0] || cmId !== undefined) { - $overlay.remove(); - callback(cmId); - } - }); - - return $overlay; - } - - function createPanel(menu) { - var $panel = $(templatePanel); - var $ul = $panel.find('ul'); - var $li; - - _.each(menu, function (entry) { - if (entry.type === '-') { - $(templateSep).appendTo($ul); - } else if (entry.type === 'l') { - $(templateLabel).appendTo($ul) - .find('.cm-text').text(entry.text); - } else if (entry.type === 'e') { - $li = $(templateEntry).appendTo($ul); - $li.data('cm-id', entry.id); - $li.find('.cm-text').text(entry.text); - if (entry.icon) { - $li.find('.cm-icon img').attr('src', resource.icon(entry.icon)); - } else { - $li.find('.cm-icon').addClass('no-icon'); - } + if (ev.target === $overlay[0] || cmId !== undefined) { + $overlay.remove(); + callback(cmId); } }); - return $panel; + return $overlay; +} + +function createPanel(menu) { + const $panel = jq(templatePanel); + const $ul = $panel.find('ul'); + let $li; + + lo.each(menu, entry => { + if (entry.type === '-') { + jq(templateSep).appendTo($ul); + } else if (entry.type === 'l') { + jq(templateLabel).appendTo($ul) + .find('.cm-text').text(entry.text); + } else if (entry.type === 'e') { + $li = jq(templateEntry).appendTo($ul); + $li.data('cm-id', entry.id); + $li.find('.cm-text').text(entry.text); + if (entry.icon) { + $li.find('.cm-icon img').attr('src', resource.icon(entry.icon)); + } else { + $li.find('.cm-icon').addClass('no-icon'); + } + } + }); + + return $panel; +} + +function positionPanel($overlay, $panel, x, y) { + const margin = 4; + + $panel.css({ + left: 0, + top: 0, + opacity: 0 + }); + $overlay.show(); + + const overlayOffset = $overlay.offset(); + const overlayLeft = overlayOffset.left; + const overlayTop = overlayOffset.top; + const overlayWidth = $overlay.outerWidth(true); + const overlayHeight = $overlay.outerHeight(true); + + // const panelOffset = $panel.offset(); + // const panelLeft = panelOffset.left; + // const panelTop = panelOffset.top; + let panelWidth = $panel.outerWidth(true); + let panelHeight = $panel.outerHeight(true); + + let posLeft = x; + let posTop = y; + + if (panelWidth > overlayWidth - 2 * margin) { + posLeft = margin; + panelWidth = overlayWidth - 2 * margin; } - function positionPanel($overlay, $panel, x, y) { - var margin = 4; - - $panel.css({ - left: 0, - top: 0, - opacity: 0 - }); - $overlay.show(); - - var overlayOffset = $overlay.offset(); - var overlayLeft = overlayOffset.left; - var overlayTop = overlayOffset.top; - var overlayWidth = $overlay.outerWidth(true); - var overlayHeight = $overlay.outerHeight(true); - - // var panelOffset = $panel.offset(); - // var panelLeft = panelOffset.left; - // var panelTop = panelOffset.top; - var panelWidth = $panel.outerWidth(true); - var panelHeight = $panel.outerHeight(true); - - var posLeft = x; - var posTop = y; - - if (panelWidth > overlayWidth - 2 * margin) { - posLeft = margin; - panelWidth = overlayWidth - 2 * margin; - } - - if (panelHeight > overlayHeight - 2 * margin) { - posTop = margin; - panelHeight = overlayHeight - 2 * margin; - } - - if (posLeft < overlayLeft + margin) { - posLeft = overlayLeft + margin; - } - - if (posLeft + panelWidth > overlayLeft + overlayWidth - margin) { - posLeft = overlayLeft + overlayWidth - margin - panelWidth; - } - - if (posTop < overlayTop + margin) { - posTop = overlayTop + margin; - } - - if (posTop + panelHeight > overlayTop + overlayHeight - margin) { - posTop = overlayTop + overlayHeight - margin - panelHeight; - } - - $panel.css({ - left: posLeft, - top: posTop, - width: panelWidth, - height: panelHeight, - opacity: 1 - }); + if (panelHeight > overlayHeight - 2 * margin) { + posTop = margin; + panelHeight = overlayHeight - 2 * margin; } - function showMenuAt(x, y, menu, callback) { - var $overlay = createOverlay(callback); - var $panel = createPanel(menu); - $overlay.append($panel).appendTo('body'); - positionPanel($overlay, $panel, x, y); + if (posLeft < overlayLeft + margin) { + posLeft = overlayLeft + margin; } - function init() { - // settings.enabled = true; - if (!settings.enabled) { - return; - } - - $(document).on('contextmenu', function (ev) { - ev.stopPropagation(); - ev.preventDefault(); - $(ev.target).trigger($.Event('h5ai-contextmenu', { - originalEvent: ev, - showMenu: function (menu, callback) { - showMenuAt(ev.pageX, ev.pageY, menu, callback); - } - })); - }); - - // var menu = [ - // {type: 'e', id: 'e1', text: 'testing context menus'}, - // {type: 'e', id: 'e2', text: 'another entry'}, - // {type: 'e', id: 'e3', text: 'one with icon', icon: 'folder'}, - // {type: '-'}, - // {type: 'e', id: 'e4', text: 'one with icon', icon: 'x'}, - // {type: 'e', id: 'e5', text: 'one with icon', icon: 'img'} - // ]; - // var callback = function (res) { - - // window.console.log('>> CB-RESULT >> ' + res); - // }; - - // $(document).on('h5ai-contextmenu', '#items .item.folder', function (ev) { - - // window.console.log('CM', ev); - // ev.showMenu(menu, callback); - // }); + if (posLeft + panelWidth > overlayLeft + overlayWidth - margin) { + posLeft = overlayLeft + overlayWidth - margin - panelWidth; } + if (posTop < overlayTop + margin) { + posTop = overlayTop + margin; + } - init(); -}); + if (posTop + panelHeight > overlayTop + overlayHeight - margin) { + posTop = overlayTop + overlayHeight - margin - panelHeight; + } + + $panel.css({ + left: posLeft, + top: posTop, + width: panelWidth, + height: panelHeight, + opacity: 1 + }); +} + +function showMenuAt(x, y, menu, callback) { + const $overlay = createOverlay(callback); + const $panel = createPanel(menu); + $overlay.append($panel).appendTo('body'); + positionPanel($overlay, $panel, x, y); +} + +function init() { + if (!settings.enabled) { + return; + } + + jq(doc).on('contextmenu', ev => { + ev.stopPropagation(); + ev.preventDefault(); + jq(ev.target).trigger(jq.Event('h5ai-contextmenu', { + originalEvent: ev, + showMenu: (menu, callback) => { + showMenuAt(ev.pageX, ev.pageY, menu, callback); + } + })); + }); + + // const menu = [ + // {type: 'e', id: 'e1', text: 'testing context menus'}, + // {type: 'e', id: 'e2', text: 'another entry'}, + // {type: 'e', id: 'e3', text: 'one with icon', icon: 'folder'}, + // {type: '-'}, + // {type: 'e', id: 'e4', text: 'one with icon', icon: 'x'}, + // {type: 'e', id: 'e5', text: 'one with icon', icon: 'img'} + // ]; + // const callback = res => { + // console.log('>> CB-RESULT >> ' + res); + // }; + // + // jq(doc).on('h5ai-contextmenu', '#items .item.folder', ev => { + // console.log('CM', ev); + // ev.showMenu(menu, callback); + // }); +} + + +init(); diff --git a/src/_h5ai/public/js/lib/ext/crumb.js b/src/_h5ai/public/js/lib/ext/crumb.js index 06c812e6..6d7f2f6e 100644 --- a/src/_h5ai/public/js/lib/ext/crumb.js +++ b/src/_h5ai/public/js/lib/ext/crumb.js @@ -1,58 +1,65 @@ -modulejs.define('ext/crumb', ['_', '$', 'core/event', 'core/location', 'core/resource', 'core/settings', 'view/topbar'], function (_, $, event, location, resource, allsettings, topbar) { - var settings = _.extend({ - enabled: false - }, allsettings.crumb); - var crumbTemplate = - '' + - '>' + - '' + - ''; - var pageHintTemplate = 'has index page'; - var $crumbbar; +const {jQuery: jq, _: lo} = require('../win'); +const event = require('../core/event'); +const location = require('../core/location'); +const resource = require('../core/resource'); +const allsettings = require('../core/settings'); +const topbar = require('../view/topbar'); - function createHtml(item) { - var $html = $(crumbTemplate).data('item', item); - item.$crumb = $html; - location.setLink($html, item); +const settings = lo.extend({ + enabled: false +}, allsettings.crumb); +const crumbTemplate = + ` + > + + `; +const pageHintTemplate = + `has index page`; +let $crumbbar; - $html.find('.label').text(item.label); - if (item.isCurrentFolder()) { - $html.addClass('active'); - } +function createHtml(item) { + const $html = jq(crumbTemplate).data('item', item); + item.$crumb = $html; + location.setLink($html, item); - if (!item.isManaged) { - $html.append($(pageHintTemplate)); - } + $html.find('.label').text(item.label); - return $html; + if (item.isCurrentFolder()) { + $html.addClass('active'); } - function onLocationChanged(item) { - var $crumb = item.$crumb; - - if ($crumb && $crumb.parent()[0] === $crumbbar[0]) { - $crumbbar.children().removeClass('active'); - $crumb.addClass('active'); - } else { - $crumbbar.empty(); - _.each(item.getCrumb(), function (crumbItem) { - $crumbbar.append(createHtml(crumbItem)); - }); - } + if (!item.isManaged) { + $html.append(jq(pageHintTemplate)); } - function init() { - if (!settings.enabled) { - return; - } + return $html; +} - $crumbbar = $('
      ').appendTo(topbar.$flowbar); +function onLocationChanged(item) { + const $crumb = item.$crumb; - event.sub('location.changed', onLocationChanged); + if ($crumb && $crumb.parent()[0] === $crumbbar[0]) { + $crumbbar.children().removeClass('active'); + $crumb.addClass('active'); + } else { + $crumbbar.empty(); + lo.each(item.getCrumb(), crumbItem => { + $crumbbar.append(createHtml(crumbItem)); + }); + } +} + +function init() { + if (!settings.enabled) { + return; } + $crumbbar = jq('
      ').appendTo(topbar.$flowbar); - init(); -}); + event.sub('location.changed', onLocationChanged); +} + + +init(); diff --git a/src/_h5ai/public/js/lib/ext/custom.js b/src/_h5ai/public/js/lib/ext/custom.js index 13138f27..7ffbfc2c 100644 --- a/src/_h5ai/public/js/lib/ext/custom.js +++ b/src/_h5ai/public/js/lib/ext/custom.js @@ -1,62 +1,66 @@ -modulejs.define('ext/custom', ['_', '$', 'marked', 'core/event', 'core/server', 'core/settings'], function (_, $, marked, event, server, allsettings) { - var settings = _.extend({ - enabled: false - }, allsettings.custom); - var $header; - var $footer; - var duration = 200; +const {jQuery: jq, _: lo, marked} = require('../win'); +const event = require('../core/event'); +const server = require('../core/server'); +const allsettings = require('../core/settings'); - function onLocationChanged(item) { - server.request({action: 'get', custom: item.absHref}, function (response) { - var custom = response && response.custom; - var hasHeader; - var hasFooter; +const settings = lo.extend({ + enabled: false +}, allsettings.custom); +let $header; +let $footer; +const duration = 200; - if (custom) { - var header = custom.header; - var footer = custom.footer; - var content; - if (header.content) { - content = header.content; - if (header.type === 'md') { - content = marked(content); - } - $header.html(content).stop().slideDown(duration); - hasHeader = true; +function onLocationChanged(item) { + server.request({action: 'get', custom: item.absHref}).then(response => { + const custom = response && response.custom; + let hasHeader; + let hasFooter; + + if (custom) { + const header = custom.header; + const footer = custom.footer; + let content; + + if (header.content) { + content = header.content; + if (header.type === 'md') { + content = marked(content); } + $header.html(content).stop().slideDown(duration); + hasHeader = true; + } - if (footer.content) { - content = footer.content; - if (footer.type === 'md') { - content = marked(content); - } - $footer.html(content).stop().slideDown(duration); - hasFooter = true; + if (footer.content) { + content = footer.content; + if (footer.type === 'md') { + content = marked(content); } + $footer.html(content).stop().slideDown(duration); + hasFooter = true; } - - if (!hasHeader) { - $header.stop().slideUp(duration); - } - if (!hasFooter) { - $footer.stop().slideUp(duration); - } - }); - } - - function init() { - if (!settings.enabled) { - return; } - $header = $('
      ').hide().prependTo('#content'); - $footer = $('