230 lines
6.6 KiB
TypeScript
230 lines
6.6 KiB
TypeScript
import './polyfills/index';
|
|
import React from 'react';
|
|
import {render as renderReact} from 'react-dom';
|
|
import axios from 'axios';
|
|
import copy from 'copy-to-clipboard';
|
|
|
|
import qs from 'qs';
|
|
import {
|
|
toast,
|
|
alert,
|
|
confirm,
|
|
ToastComponent,
|
|
AlertComponent,
|
|
render as renderAmis
|
|
} from '../src/index';
|
|
|
|
export function embed(
|
|
container: string | HTMLElement,
|
|
schema: any,
|
|
data: any,
|
|
env: any
|
|
) {
|
|
if (typeof container === 'string') {
|
|
container = document.querySelector(container) as HTMLElement;
|
|
}
|
|
if (!container) {
|
|
console.error('选择器不对,页面上没有此元素');
|
|
return;
|
|
} else if (container.tagName === 'BODY') {
|
|
let div = document.createElement('div');
|
|
container.appendChild(div);
|
|
container = div;
|
|
}
|
|
container.classList.add('amis-scope');
|
|
let scoped: any;
|
|
const normalizeLink = (to: string) => {
|
|
to = to || '';
|
|
const location = window.location;
|
|
|
|
if (to && to[0] === '#') {
|
|
to = location.pathname + location.search + to;
|
|
} else if (to && to[0] === '?') {
|
|
to = location.pathname + to;
|
|
}
|
|
|
|
const idx = to.indexOf('?');
|
|
const idx2 = to.indexOf('#');
|
|
let pathname = ~idx
|
|
? to.substring(0, idx)
|
|
: ~idx2
|
|
? to.substring(0, idx2)
|
|
: to;
|
|
let search = ~idx ? to.substring(idx, ~idx2 ? idx2 : undefined) : '';
|
|
let hash = ~idx2 ? to.substring(idx2) : location.hash;
|
|
|
|
if (!pathname) {
|
|
pathname = location.pathname;
|
|
} else if (pathname[0] != '/' && !/^https?\:\/\//.test(pathname)) {
|
|
let relativeBase = location.pathname;
|
|
const paths = relativeBase.split('/');
|
|
paths.pop();
|
|
let m;
|
|
while ((m = /^\.\.?\//.exec(pathname))) {
|
|
if (m[0] === '../') {
|
|
paths.pop();
|
|
}
|
|
pathname = pathname.substring(m[0].length);
|
|
}
|
|
pathname = paths.concat(pathname).join('/');
|
|
}
|
|
|
|
return pathname + search + hash;
|
|
};
|
|
|
|
const responseAdpater = (api: any) => (value: any) => {
|
|
let response = value.data;
|
|
if (env && env.responseAdpater) {
|
|
const url = api.url;
|
|
const idx = api.url.indexOf('?');
|
|
const query = ~idx ? qs.parse(api.url.substring(idx)) : {};
|
|
const request = {
|
|
...api,
|
|
query: query,
|
|
body: api.data
|
|
};
|
|
response = env.responseAdpater(api, response, query, request);
|
|
} else {
|
|
if (response.hasOwnProperty('errno')) {
|
|
response.status = response.errno;
|
|
response.msg = response.errmsg;
|
|
} else if (response.hasOwnProperty('no')) {
|
|
response.status = response.no;
|
|
response.msg = response.error;
|
|
}
|
|
}
|
|
|
|
const result = {
|
|
...value,
|
|
data: response
|
|
};
|
|
return result;
|
|
};
|
|
|
|
renderReact(
|
|
<div className="amis-routes-wrapper">
|
|
<ToastComponent
|
|
position={(env && env.toastPosition) || 'top-right'}
|
|
closeButton={false}
|
|
timeOut={5000}
|
|
extendedTimeOut={3000}
|
|
/>
|
|
<AlertComponent container={container} />
|
|
|
|
{renderAmis(
|
|
schema,
|
|
{
|
|
...data,
|
|
scopeRef: (ref: any) => (scoped = ref)
|
|
},
|
|
{
|
|
getModalContainer: () => document.querySelector('.amis-scope'),
|
|
notify: (type: string, msg: string) =>
|
|
toast[type]
|
|
? toast[type](msg, type === 'error' ? '系统错误' : '系统消息')
|
|
: console.warn('[Notify]', type, msg),
|
|
alert,
|
|
confirm,
|
|
updateLocation: (to: any, replace: boolean) => {
|
|
if (to === 'goBack') {
|
|
return window.history.back();
|
|
}
|
|
|
|
replace || (location.href = normalizeLink(to));
|
|
},
|
|
isCurrentUrl: (to: string) => {
|
|
const link = normalizeLink(to);
|
|
const location = window.location;
|
|
let pathname = link;
|
|
let search = '';
|
|
const idx = link.indexOf('?');
|
|
if (~idx) {
|
|
pathname = link.substring(0, idx);
|
|
search = link.substring(idx);
|
|
}
|
|
|
|
if (search) {
|
|
if (pathname !== location.pathname || !location.search) {
|
|
return false;
|
|
}
|
|
|
|
const query = qs.parse(search.substring(1));
|
|
const currentQuery = qs.parse(location.search.substring(1));
|
|
|
|
return Object.keys(query).every(
|
|
key => query[key] === currentQuery[key]
|
|
);
|
|
} else if (pathname === location.pathname) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
},
|
|
jumpTo: (to: string, action?: any) => {
|
|
if (to === 'goBack') {
|
|
return window.history.back();
|
|
}
|
|
|
|
to = normalizeLink(to);
|
|
|
|
if (action && action.actionType === 'url') {
|
|
action.blank === false
|
|
? (window.location.href = to)
|
|
: window.open(to);
|
|
return;
|
|
}
|
|
|
|
if (/^https?:\/\//.test(to)) {
|
|
window.location.replace(to);
|
|
} else {
|
|
location.href = to;
|
|
}
|
|
},
|
|
fetcher: (api: any) => {
|
|
let {url, method, data, responseType, config, headers} = api;
|
|
config = config || {};
|
|
config.withCredentials = true;
|
|
responseType && (config.responseType = responseType);
|
|
|
|
if (config.cancelExecutor) {
|
|
config.cancelToken = new (axios as any).CancelToken(
|
|
config.cancelExecutor
|
|
);
|
|
}
|
|
|
|
config.headers = headers || {};
|
|
config.method = method;
|
|
|
|
if (method === 'get' && data) {
|
|
config.params = data;
|
|
} else if (data && data instanceof FormData) {
|
|
// config.headers['Content-Type'] = 'multipart/form-data';
|
|
} else if (
|
|
data &&
|
|
typeof data !== 'string' &&
|
|
!(data instanceof Blob) &&
|
|
!(data instanceof ArrayBuffer)
|
|
) {
|
|
data = JSON.stringify(data);
|
|
config.headers['Content-Type'] = 'application/json';
|
|
}
|
|
|
|
data && (config.data = data);
|
|
return axios(url, config).then(responseAdpater(api));
|
|
},
|
|
isCancel: (value: any) => (axios as any).isCancel(value),
|
|
copy: (contents: string, options: any = {}) => {
|
|
const ret = copy(contents, options);
|
|
ret && options.shutup !== true && toast.info('内容已拷贝到剪切板');
|
|
return ret;
|
|
},
|
|
richTextToken: '',
|
|
...env
|
|
}
|
|
)}
|
|
</div>,
|
|
container
|
|
);
|
|
return scoped;
|
|
}
|