ui-default: init

将ui-default合并至主存储库便于维护
This commit is contained in:
undefined committed 2021-04-03 01:44:22 +08:00
1 parent 6317c9057f
commit 5faa54c7ca
564 files changed
+23083 -14

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
export default function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
window.Hydro.utils.delay = delay;
@@ -0,0 +1,20 @@
/**
* @param {Event} ev
* @param {String} targetUrl
* @param {Boolean} alwaysOpenInNewWindow
*/
export default function emulateAnchorClick(ev, targetUrl, alwaysOpenInNewWindow = false) {
let openInNewWindow;
if (alwaysOpenInNewWindow) {
openInNewWindow = true;
} else {
openInNewWindow = (ev.ctrlKey || ev.shiftKey || ev.metaKey);
}
if (openInNewWindow) {
window.open(targetUrl);
} else {
window.location.href = targetUrl;
}
}
window.Hydro.utils.emulateAnchorClick = emulateAnchorClick;
+10
View File
@@ -0,0 +1,10 @@
import substitute from './substitute';
export default function i18n(str, ...params) {
if (window.LOCALES && window.LOCALES[str]) {
return substitute(window.LOCALES[str], params);
}
return substitute(str, params);
}
window.Hydro.utils.i18n = i18n;
@@ -0,0 +1,32 @@
export default async function loadReactRedux(storeReducer) {
const React = await import('react');
const { render, unmountComponentAtNode } = await import('react-dom');
const { Provider } = await import('react-redux');
const { createStore, applyMiddleware } = await import('redux');
const { default: reduxThunk } = await import('redux-thunk');
const { default: reduxPromise } = await import('redux-promise-middleware');
const reduxMiddlewares = [];
reduxMiddlewares.push(reduxThunk);
reduxMiddlewares.push(reduxPromise);
if (process.env.NODE_ENV !== 'production') {
const { createLogger } = await import('redux-logger');
reduxMiddlewares.push(createLogger({
collapsed: true,
duration: true,
}));
}
const store = createStore(storeReducer, applyMiddleware(...reduxMiddlewares));
return {
React,
render,
unmountComponentAtNode,
Provider,
store,
};
}
window.Hydro.utils.loadReactRedux = loadReactRedux;
+16
View File
@@ -0,0 +1,16 @@
export function isAbove(width) {
if (window.matchMedia) {
return window.matchMedia(`(min-width: ${width}px)`).matches;
}
return window.innerWidth >= width;
}
export function isBelow(width) {
if (window.matchMedia) {
return window.matchMedia(`(max-width: ${width}px)`).matches;
}
return window.innerWidth <= width;
}
window.Hydro.utils.isAbove = isAbove;
window.Hydro.utils.isBelow = isBelow;
+16
View File
@@ -0,0 +1,16 @@
/* eslint-disable */
// https://github.com/andrasq/node-mongoid-js/blob/master/mongoid.js
export function parse(idstring) {
if (typeof idstring !== 'string') {
idstring = String(idstring);
}
return {
timestamp: parseInt(idstring.slice( 0, 0+8), 16),
machineid: parseInt(idstring.slice( 8, 8+6), 16),
pid: parseInt(idstring.slice(14, 14+4), 16),
sequence: parseInt(idstring.slice(18, 18+6), 16),
};
}
window.Hydro.utils.mongoId = parse;
@@ -0,0 +1,13 @@
export default function parseQueryString(str) {
const obj = {};
(str || document.location.search)
.replace(/(^\?)/, '')
.split('&')
.forEach((n) => {
const [key, value] = n.split('=').map((v) => decodeURIComponent(v));
obj[key] = value;
});
return obj;
}
window.Hydro.utils.parseQueryString = parseQueryString;
+21
View File
@@ -0,0 +1,21 @@
export default async function pipeStream(read, write, abort) {
if (window.WritableStream && read.pipeTo) {
const abortController = new AbortController();
if (abort) abort.abort = abortController.abort.bind(abortController);
await read.pipeTo(write, abortController);
} else {
const writer = write.getWriter();
if (abort) abort.abort = writer.abort.bind(writer);
const reader = read.getReader();
// eslint-disable-next-line no-constant-condition
while (1) {
const readResult = await reader.read();
if (readResult.done) {
writer.close();
break;
} else writer.write(readResult.value);
}
}
}
window.Hydro.utils.pipeStream = pipeStream;
+150
View File
@@ -0,0 +1,150 @@
// Modified from jquery-pjax to support multiple fragments and jQuery 3.0
// https://github.com/defunkt/jquery-pjax/blob/master/jquery.pjax.js
import { v4 as uuid } from 'uuid';
import Notification from 'vj/components/notification';
import NProgress from 'vj/components/nprogress';
import request from './request';
const pjax = {};
let currentState = null;
let currentXHR = null;
let inProgress = 0;
function cancelLastXHR() {
if (currentXHR && currentXHR.readyState < 4) {
currentXHR.abort();
currentXHR = null;
}
}
function canonicalizeUrl(url) {
const a = document.createElement('a');
a.href = url;
return a.href;
}
function extractMetaData(requestOption, response) {
const metaData = {
title: response.title ? response.title : document.title,
url: response.url ? response.url : requestOption.url,
};
metaData.url = canonicalizeUrl(metaData.url);
return metaData;
}
function incProgress() {
inProgress++;
NProgress.done();
NProgress.start();
}
function decProgress() {
inProgress--;
if (inProgress === 0) {
NProgress.done();
}
}
pjax.request = async (opt) => {
const options = {
method: 'get',
push: true,
...opt,
};
if (!currentState) {
// create initial state
currentState = {
id: uuid(),
options: {
url: window.location.href,
},
};
window.history.replaceState(currentState, null);
}
cancelLastXHR();
if (options.push) {
// in popstate, options.push === false
window.history.pushState(null, null, options.url);
}
incProgress();
try {
const data = await request.ajax({
beforeSend(xhr) {
currentXHR = xhr;
},
...options,
});
const meta = extractMetaData(options, data);
currentState = {
id: uuid(),
options: opt,
};
if (options.push) {
window.history.replaceState(currentState, null, meta.url);
}
document.title = meta.title;
data.fragments.forEach((fragment) => {
if (process.env.NODE_ENV !== 'production') {
if (fragment.html === undefined) {
// eslint-disable-next-line quotes
throw new Error(`Fragement should contain 'html'`);
}
}
const $el = $(fragment.html.trim());
if (process.env.NODE_ENV !== 'production') {
if ($el.length === 0) {
// eslint-disable-next-line quotes
throw new Error(`Unable to build elements from fragment 'html'`);
}
}
const fragmentId = $el.attr('data-fragment-id');
if (process.env.NODE_ENV !== 'production') {
if (!fragmentId) {
// eslint-disable-next-line quotes
throw new Error(`Unable to extract fragment id from fragment 'html'`);
}
}
const $target = $(`[data-fragment-id="${fragmentId}"]`);
if (process.env.NODE_ENV !== 'production') {
if ($target.length === 0) {
// eslint-disable-next-line quotes
throw new Error(`Unable to get target fragment from fragment id`);
}
}
$target.trigger('vjContentRemove');
$target.replaceWith($el);
$el.trigger('vjContentNew');
});
} catch (err) {
if (!err.aborted) {
Notification.error(err.message);
console.log(err);
}
} finally {
decProgress();
}
};
function handlePopState(ev) {
if (!ev.originalEvent) {
return;
}
const { state } = ev.originalEvent;
if (!state) {
return;
}
if (!state.id || (currentState && state.id === currentState.id)) {
return;
}
pjax.request({
...state.options,
push: false,
});
}
$(window).on('popstate', handlePopState);
export default pjax;
window.Hydro.utils.pjax = pjax;
+95
View File
@@ -0,0 +1,95 @@
import i18n from './i18n';
const request = {
/**
* @param {object} options
*/
async ajax(options) {
return new Promise((resolve, reject) => {
$
.ajax({
dataType: 'json',
...options,
})
.fail((jqXHR, textStatus, errorThrown) => {
if (textStatus === 'abort') {
const err = new Error(i18n('Aborted'));
err.aborted = true;
reject(err);
} else if (jqXHR.readyState === 0) {
reject(new Error(i18n('Network error')));
} else if (errorThrown instanceof Error) {
reject(errorThrown);
} else if (typeof jqXHR.responseJSON === 'object' && jqXHR.responseJSON.error) {
reject(new Error(jqXHR.responseJSON.error.message));
} else {
reject(new Error(textStatus));
}
})
.done(resolve);
});
},
/**
* @param {string} url
* @param {FormData} FormData
*/
postFile(url, form) {
return this.ajax({
url,
data: form,
processData: false,
contentType: false,
type: 'POST',
dataType: undefined,
});
},
/**
* @param {string} url
* @param {JQueryStatic | Node | string | object} dataOrForm
* @param {object} options
*/
post(url, dataOrForm = {}, options = {}) {
let postData;
if (dataOrForm instanceof jQuery && dataOrForm.is('form')) {
// $form
postData = dataOrForm.serialize();
} else if (dataOrForm instanceof Node && $(dataOrForm).is('form')) {
// form
postData = $(dataOrForm).serialize();
} else if (typeof dataOrForm === 'string') {
// foo=bar&box=boz
postData = dataOrForm;
} else {
// {foo: 'bar'}
postData = $.param({
csrfToken: UiContext.csrfToken,
...dataOrForm,
}, true);
}
return request.ajax({
url,
method: 'post',
data: postData,
...options,
});
},
/**
* @param {string} url
* @param {object} qs
* @param {object} options
*/
get(url, qs = {}, options = {}) {
return request.ajax({
url,
data: qs,
method: 'get',
...options,
});
},
};
export default request;
window.Hydro.utils.request = request;
+59
View File
@@ -0,0 +1,59 @@
import 'jquery.easing';
export async function slideDown($element, duration, fromCss = {}, toCss = {}) {
const originalStyl = $element.attr('style') || '';
$element.css({
position: 'absolute',
visibility: 'none',
display: 'block',
});
const height = $element.outerHeight();
$element.attr('style', originalStyl);
$element.css({
height: 0,
overflow: 'hidden',
display: 'block',
...fromCss,
});
$element.height();
await $element
.transition({
height,
...toCss,
}, {
duration,
easing: 'easeOutCubic',
})
.promise();
$element.attr('style', originalStyl);
$element.css({
display: 'block',
});
}
export async function slideUp($element, duration, fromCss = {}, toCss = {}) {
const originalStyl = $element.attr('style') || '';
const height = $element.outerHeight();
$element.css({
height,
overflow: 'hidden',
display: 'block',
...fromCss,
});
$element.height();
await $element
.transition({
height: 0,
...toCss,
}, {
duration,
easing: 'easeOutCubic',
})
.promise();
$element.attr('style', originalStyl);
$element.css({
display: 'none',
});
}
window.Hydro.utils.slide = { slideUp, slideDown };
+10
View File
@@ -0,0 +1,10 @@
export default function substitute(str, obj) {
return str.replace(/\{([^{}]+)\}/g, (match, key) => {
if (obj[key] !== undefined) {
return String(obj[key]);
}
return `{${key}}`;
});
}
window.Hydro.utils.substitute = substitute;
+23
View File
@@ -0,0 +1,23 @@
import _ from 'lodash';
export default function tpl(pieces, ...substitutions) {
let result = pieces[0];
for (let i = 0; i < substitutions.length; ++i) {
const subst = substitutions[i];
let substHtml;
if (typeof subst === 'object' && subst.templateRaw) {
substHtml = subst.html;
} else substHtml = _.escape(String(subst));
result += substHtml + pieces[i + 1];
}
return result;
}
export function rawHtml(html) {
return {
templateRaw: true,
html,
};
}
global.Hydro.utils.tpl = tpl;
@@ -0,0 +1,13 @@
let zIndexCurrent = 1000;
const manager = {
getCurrent() {
return zIndexCurrent;
},
getNext() {
return ++zIndexCurrent;
},
};
export default manager;
window.Hydro.utils.zIndexManager = manager;
+9
View File
@@ -0,0 +1,9 @@
import 'streamsaver/examples/zip-stream';
export const createZipStream = window.ZIP;
export async function createZipBlob(underlyingSource) {
return new Response(createZipStream(underlyingSource)).blob();
}
window.Hydro.utils.zip = { createZipStream, createZipBlob };