mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 09:46:28 +08:00
ui-default: init
将ui-default合并至主存储库便于维护
This commit is contained in:
1 parent
6317c9057f
commit
5faa54c7ca
564 files changed
+23083
-14
No files matched your search
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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 };
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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 };
|
||||
Reference in new issue
Block a user