xframelib 0.4.0 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/api/Token.d.ts +20 -0
- package/dist/api/User.d.ts +45 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/controls/collapsepanel/VCollapsiblePanel.vue.d.ts +26 -0
- package/dist/controls/collapsepanel/VCollapsiblePanelGroup.vue.d.ts +30 -0
- package/dist/controls/collapsepanel/color.util.d.ts +1 -0
- package/dist/controls/collapsepanel/composables/store.d.ts +7 -0
- package/dist/controls/collapsepanel/constant.d.ts +1 -0
- package/dist/controls/collapsepanel/index.d.ts +3 -0
- package/dist/controls/layoutcontainer/LayoutManager.d.ts +107 -0
- package/dist/controls/layoutcontainer/index.d.ts +3 -0
- package/dist/controls/layoutcontainer/layout.vue.d.ts +37 -0
- package/dist/controls/splitpanes/index.d.ts +3 -0
- package/dist/controls/vuewindow/SinglePointerEvent.d.ts +23 -0
- package/dist/controls/vuewindow/dom.d.ts +16 -0
- package/dist/controls/vuewindow/draggable_helper.d.ts +20 -0
- package/dist/controls/vuewindow/index.d.ts +6 -0
- package/dist/controls/vuewindow/resizable_helper.d.ts +16 -0
- package/dist/controls/vuewindow/style.d.ts +110 -0
- package/dist/controls/vuewindow/window/Button.vue.d.ts +26 -0
- package/dist/controls/vuewindow/window/index.vue.d.ts +160 -0
- package/dist/controls/vuewindow/window/utils.d.ts +17 -0
- package/dist/controls/vuewindow/z_element.d.ts +11 -0
- package/dist/core/Global.d.ts +26 -0
- package/dist/core/IModel.d.ts +34 -0
- package/dist/core/MsgHelper.d.ts +12 -0
- package/dist/core/SysEvents.d.ts +16 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/hprose/HproseClient.d.ts +20 -0
- package/dist/hprose/ProxyClient.d.ts +22 -0
- package/dist/hprose/index.d.ts +11 -0
- package/dist/index.cjs +3 -3
- package/dist/index.css +69 -0
- package/dist/index.d.ts +10 -1024
- package/dist/index.js +3 -3
- package/dist/mitt/index.d.ts +25 -0
- package/dist/model/Config.d.ts +94 -0
- package/dist/model/Constants.d.ts +15 -0
- package/dist/model/Layout.d.ts +75 -0
- package/dist/model/Token.d.ts +66 -0
- package/dist/model/index.d.ts +4 -0
- package/dist/public/mitm.html +166 -0
- package/dist/public/sw.js +128 -0
- package/dist/utils/AxiosHelper.d.ts +51 -0
- package/dist/utils/BigFileDownload.d.ts +106 -0
- package/dist/utils/Color.d.ts +74 -0
- package/dist/utils/FileDownload.d.ts +36 -0
- package/dist/utils/FileUpload.d.ts +90 -0
- package/dist/utils/H5Tool.d.ts +98 -0
- package/dist/utils/IsTool.d.ts +101 -0
- package/dist/utils/JQuery.d.ts +35 -0
- package/dist/utils/LockHelper.d.ts +17 -0
- package/dist/utils/Storage.d.ts +57 -0
- package/dist/utils/StringUtils.d.ts +15 -0
- package/dist/utils/Time.d.ts +1 -0
- package/dist/utils/TokenHelper.d.ts +18 -0
- package/dist/utils/URLTool.d.ts +18 -0
- package/dist/utils/index.d.ts +16 -0
- package/dist/utils/uuid.d.ts +3 -0
- package/package.json +15 -15
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare type EventType = string | symbol;
|
|
2
|
+
export declare type Handler<T = any> = (event?: T) => void;
|
|
3
|
+
export declare type WildcardHandler = (type: EventType, event?: any) => void;
|
|
4
|
+
export declare type EventHandlerList = Array<Handler>;
|
|
5
|
+
export declare type WildCardEventHandlerList = Array<WildcardHandler>;
|
|
6
|
+
export declare type EventHandlerMap = Map<EventType, EventHandlerList | WildCardEventHandlerList>;
|
|
7
|
+
export interface Emitter {
|
|
8
|
+
all: EventHandlerMap;
|
|
9
|
+
on<T = any>(type: EventType, handler: Handler<T>): void;
|
|
10
|
+
on(type: '*', handler: WildcardHandler): void;
|
|
11
|
+
off<T = any>(type: EventType, handler: Handler<T>): void;
|
|
12
|
+
off(type: '*', handler: WildcardHandler): void;
|
|
13
|
+
emit<T = any>(type: EventType, event?: T): void;
|
|
14
|
+
emit(type: '*', event?: any): void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Mitt: Tiny (~200b) functional event emitter / pubsub.
|
|
18
|
+
* @name mitt
|
|
19
|
+
* @returns {Mitt}
|
|
20
|
+
*/
|
|
21
|
+
export default function mitt(all?: EventHandlerMap): Emitter;
|
|
22
|
+
/**
|
|
23
|
+
* 默认全局总线对象
|
|
24
|
+
*/
|
|
25
|
+
export declare const GlobalMitt: Emitter;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI界面相关
|
|
3
|
+
*/
|
|
4
|
+
export interface IUIObject {
|
|
5
|
+
/**
|
|
6
|
+
* 网站标题
|
|
7
|
+
*/
|
|
8
|
+
SiteTitle: string;
|
|
9
|
+
/**
|
|
10
|
+
* 版权
|
|
11
|
+
*/
|
|
12
|
+
CopyRight: string;
|
|
13
|
+
/**
|
|
14
|
+
* 官方链接
|
|
15
|
+
*/
|
|
16
|
+
WebSite?: string;
|
|
17
|
+
/**
|
|
18
|
+
* 超时锁屏时间(单位:秒s)
|
|
19
|
+
*/
|
|
20
|
+
LockTime?: number;
|
|
21
|
+
/**
|
|
22
|
+
* 其他扩展的属性
|
|
23
|
+
*/
|
|
24
|
+
[props: string]: any;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 服务URL
|
|
28
|
+
*/
|
|
29
|
+
export interface IServiceURL {
|
|
30
|
+
/**
|
|
31
|
+
* 用户登录(统一用户登录)
|
|
32
|
+
*/
|
|
33
|
+
LoginAuthURL: string;
|
|
34
|
+
/**
|
|
35
|
+
* Axios普通WebAPI的BaseURL
|
|
36
|
+
* 全局默认的http请求地址(一般与主hprose相同或不同);文件上传地址
|
|
37
|
+
*/
|
|
38
|
+
DefaultWebAPI?: string;
|
|
39
|
+
/**
|
|
40
|
+
* 默认HproseAPI的服务地址
|
|
41
|
+
*/
|
|
42
|
+
DefaultHproseAPI?: string;
|
|
43
|
+
/**
|
|
44
|
+
* 其他扩展的URL属性
|
|
45
|
+
*/
|
|
46
|
+
[props: string]: any;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 地图相关Keys
|
|
50
|
+
*/
|
|
51
|
+
export interface IMapKeys {
|
|
52
|
+
/**
|
|
53
|
+
* 天地图Key
|
|
54
|
+
*/
|
|
55
|
+
TDTKey?: string;
|
|
56
|
+
/**
|
|
57
|
+
* MapboxKey
|
|
58
|
+
*/
|
|
59
|
+
MapboxKey?: string;
|
|
60
|
+
/**
|
|
61
|
+
* Cesium Key
|
|
62
|
+
*/
|
|
63
|
+
CesiumKey?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Google地图Key
|
|
66
|
+
*/
|
|
67
|
+
GoogleKey?: string;
|
|
68
|
+
/**
|
|
69
|
+
* 其他扩展的Key属性
|
|
70
|
+
*/
|
|
71
|
+
[props: string]: any;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 系统配置信息
|
|
75
|
+
*/
|
|
76
|
+
export interface ISystemConfig {
|
|
77
|
+
/**
|
|
78
|
+
* 用户界面配置
|
|
79
|
+
*/
|
|
80
|
+
UI?: IUIObject;
|
|
81
|
+
/**
|
|
82
|
+
* 服务URL
|
|
83
|
+
*/
|
|
84
|
+
ServiceURL: IServiceURL;
|
|
85
|
+
/**
|
|
86
|
+
* 地图相关Keys
|
|
87
|
+
*/
|
|
88
|
+
MapKeys?: IMapKeys;
|
|
89
|
+
/**
|
|
90
|
+
* API服务路径
|
|
91
|
+
*/
|
|
92
|
+
APIPath?: object;
|
|
93
|
+
[props: string]: any;
|
|
94
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 刷新提前量(毫秒,ms)
|
|
3
|
+
*/
|
|
4
|
+
export declare const TOKEN_REFRESH_TIME: number;
|
|
5
|
+
/**
|
|
6
|
+
* 用户和Token相关服务API
|
|
7
|
+
*/
|
|
8
|
+
export declare const USER_TOKEN_API: {
|
|
9
|
+
Login: string;
|
|
10
|
+
CheckLogin: string;
|
|
11
|
+
Logout: string;
|
|
12
|
+
ChangePWD: string;
|
|
13
|
+
RefreshToken: string;
|
|
14
|
+
CheckToken: string;
|
|
15
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Component } from 'vue';
|
|
2
|
+
export declare type Lazy<T> = () => Promise<T>;
|
|
3
|
+
/**
|
|
4
|
+
*布局枚举类型
|
|
5
|
+
*/
|
|
6
|
+
export declare enum LayoutContainerEnum {
|
|
7
|
+
top = 0,
|
|
8
|
+
bottom = 1,
|
|
9
|
+
centerBack = 2,
|
|
10
|
+
centerMain = 3,
|
|
11
|
+
centerFront = 4,
|
|
12
|
+
left = 5,
|
|
13
|
+
right = 6
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* 组件布局
|
|
17
|
+
*/
|
|
18
|
+
export interface IWidgetLayout {
|
|
19
|
+
top?: number;
|
|
20
|
+
left?: number;
|
|
21
|
+
right?: number;
|
|
22
|
+
bottom?: number;
|
|
23
|
+
width?: string;
|
|
24
|
+
height?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface IWidgetConfig {
|
|
27
|
+
/**
|
|
28
|
+
* 唯一ID,与组件名一致
|
|
29
|
+
*/
|
|
30
|
+
id: string;
|
|
31
|
+
/**
|
|
32
|
+
* 标题或说明
|
|
33
|
+
*/
|
|
34
|
+
label?: string;
|
|
35
|
+
/**
|
|
36
|
+
* 图标路径(备用)
|
|
37
|
+
*/
|
|
38
|
+
icon?: string;
|
|
39
|
+
/**
|
|
40
|
+
* 所属容器,top/bottom/left/right等
|
|
41
|
+
*/
|
|
42
|
+
container: LayoutContainerEnum;
|
|
43
|
+
/**
|
|
44
|
+
* 外部组件js url(备用)
|
|
45
|
+
*/
|
|
46
|
+
jsURL?: string;
|
|
47
|
+
/**
|
|
48
|
+
* 外部组件css url(备用)
|
|
49
|
+
*/
|
|
50
|
+
cssURL?: string;
|
|
51
|
+
/**
|
|
52
|
+
* 动态加载的组件
|
|
53
|
+
*/
|
|
54
|
+
component: Lazy<Component>;
|
|
55
|
+
/**
|
|
56
|
+
* 是否初始化时,预加载
|
|
57
|
+
*/
|
|
58
|
+
preload?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* 前置容器ID,一般也就是bindid
|
|
61
|
+
*/
|
|
62
|
+
afterid?: string;
|
|
63
|
+
/**
|
|
64
|
+
* 绑定依赖容器ID,不一定有afterid
|
|
65
|
+
*/
|
|
66
|
+
bindid?: string;
|
|
67
|
+
/**
|
|
68
|
+
* 所属组,用于业务分类
|
|
69
|
+
*/
|
|
70
|
+
group?: string;
|
|
71
|
+
/**
|
|
72
|
+
* 外部定义布局(备用)
|
|
73
|
+
*/
|
|
74
|
+
layout?: IWidgetLayout;
|
|
75
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 当前存储的token对象
|
|
3
|
+
*/
|
|
4
|
+
export interface ITokenInfo {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
token: string;
|
|
8
|
+
expire: string;
|
|
9
|
+
refresh: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 单个token对象内容
|
|
13
|
+
* 与后台相匹配
|
|
14
|
+
*/
|
|
15
|
+
export interface IToken {
|
|
16
|
+
/**
|
|
17
|
+
* token内容
|
|
18
|
+
*/
|
|
19
|
+
tokenContent: string;
|
|
20
|
+
/**
|
|
21
|
+
* 超时时间
|
|
22
|
+
*/
|
|
23
|
+
expires: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 双Token接口定义
|
|
27
|
+
*/
|
|
28
|
+
export interface IDoubleToken {
|
|
29
|
+
/**
|
|
30
|
+
* 当前有效token
|
|
31
|
+
*/
|
|
32
|
+
accessToken: IToken;
|
|
33
|
+
/**
|
|
34
|
+
* 用于刷新的token
|
|
35
|
+
*/
|
|
36
|
+
refreshToken: IToken;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 系统用户
|
|
40
|
+
*/
|
|
41
|
+
export interface ISystemUser {
|
|
42
|
+
/**
|
|
43
|
+
* 用户ID
|
|
44
|
+
*/
|
|
45
|
+
id: string;
|
|
46
|
+
/**
|
|
47
|
+
* 用户名
|
|
48
|
+
*/
|
|
49
|
+
name: string;
|
|
50
|
+
/**
|
|
51
|
+
* 用户组ID
|
|
52
|
+
*/
|
|
53
|
+
groupid?: string;
|
|
54
|
+
photo?: string;
|
|
55
|
+
mobile?: string;
|
|
56
|
+
qq?: string;
|
|
57
|
+
email?: string;
|
|
58
|
+
img?: string;
|
|
59
|
+
issystem?: boolean;
|
|
60
|
+
createtime?: string;
|
|
61
|
+
updatetime?: string;
|
|
62
|
+
issecurity?: boolean;
|
|
63
|
+
appkey?: string;
|
|
64
|
+
role?: string;
|
|
65
|
+
doubleToken?: IDoubleToken;
|
|
66
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
mitm.html is the lite "man in the middle"
|
|
3
|
+
|
|
4
|
+
This is only meant to signal the opener's messageChannel to
|
|
5
|
+
the service worker - when that is done this mitm can be closed
|
|
6
|
+
but it's better to keep it alive since this also stops the sw
|
|
7
|
+
from restarting
|
|
8
|
+
|
|
9
|
+
The service worker is capable of intercepting all request and fork their
|
|
10
|
+
own "fake" response - wish we are going to craft
|
|
11
|
+
when the worker then receives a stream then the worker will tell the opener
|
|
12
|
+
to open up a link that will start the download
|
|
13
|
+
-->
|
|
14
|
+
<script>
|
|
15
|
+
// This will prevent the sw from restarting
|
|
16
|
+
let keepAlive = () => {
|
|
17
|
+
keepAlive = () => {}
|
|
18
|
+
var ping = location.href.substr(0, location.href.lastIndexOf('/')) + '/ping'
|
|
19
|
+
var interval = setInterval(() => {
|
|
20
|
+
if (sw) {
|
|
21
|
+
sw.postMessage('ping')
|
|
22
|
+
} else {
|
|
23
|
+
fetch(ping).then(res => res.text(!res.ok && clearInterval(interval)))
|
|
24
|
+
}
|
|
25
|
+
}, 10000)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// message event is the first thing we need to setup a listner for
|
|
29
|
+
// don't want the opener to do a random timeout - instead they can listen for
|
|
30
|
+
// the ready event
|
|
31
|
+
// but since we need to wait for the Service Worker registration, we store the
|
|
32
|
+
// message for later
|
|
33
|
+
let messages = []
|
|
34
|
+
window.onmessage = evt => messages.push(evt)
|
|
35
|
+
|
|
36
|
+
let sw = null
|
|
37
|
+
let scope = ''
|
|
38
|
+
|
|
39
|
+
function registerWorker() {
|
|
40
|
+
return navigator.serviceWorker.getRegistration('./').then(swReg => {
|
|
41
|
+
return swReg || navigator.serviceWorker.register('sw.js', { scope: './' })
|
|
42
|
+
}).then(swReg => {
|
|
43
|
+
const swRegTmp = swReg.installing || swReg.waiting
|
|
44
|
+
|
|
45
|
+
scope = swReg.scope
|
|
46
|
+
|
|
47
|
+
return (sw = swReg.active) || new Promise(resolve => {
|
|
48
|
+
swRegTmp.addEventListener('statechange', fn = () => {
|
|
49
|
+
if (swRegTmp.state === 'activated') {
|
|
50
|
+
swRegTmp.removeEventListener('statechange', fn)
|
|
51
|
+
sw = swReg.active
|
|
52
|
+
resolve()
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Now that we have the Service Worker registered we can process messages
|
|
60
|
+
function onMessage (event) {
|
|
61
|
+
let { data, ports, origin } = event
|
|
62
|
+
|
|
63
|
+
// It's important to have a messageChannel, don't want to interfere
|
|
64
|
+
// with other simultaneous downloads
|
|
65
|
+
if (!ports || !ports.length) {
|
|
66
|
+
throw new TypeError("[StreamSaver] You didn't send a messageChannel")
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (typeof data !== 'object') {
|
|
70
|
+
throw new TypeError("[StreamSaver] You didn't send a object")
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// the default public service worker for StreamSaver is shared among others.
|
|
74
|
+
// so all download links needs to be prefixed to avoid any other conflict
|
|
75
|
+
data.origin = origin
|
|
76
|
+
|
|
77
|
+
// if we ever (in some feature versoin of streamsaver) would like to
|
|
78
|
+
// redirect back to the page of who initiated a http request
|
|
79
|
+
data.referrer = data.referrer || document.referrer || origin
|
|
80
|
+
|
|
81
|
+
// pass along version for possible backwards compatibility in sw.js
|
|
82
|
+
data.streamSaverVersion = new URLSearchParams(location.search).get('version')
|
|
83
|
+
|
|
84
|
+
if (data.streamSaverVersion === '1.2.0') {
|
|
85
|
+
console.warn('[StreamSaver] please update streamsaver')
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** @since v2.0.0 */
|
|
89
|
+
if (!data.headers) {
|
|
90
|
+
console.warn("[StreamSaver] pass `data.headers` that you would like to pass along to the service worker\nit should be a 2D array or a key/val object that fetch's Headers api accepts")
|
|
91
|
+
} else {
|
|
92
|
+
// test if it's correct
|
|
93
|
+
// should thorw a typeError if not
|
|
94
|
+
new Headers(data.headers)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** @since v2.0.0 */
|
|
98
|
+
if (typeof data.filename === 'string') {
|
|
99
|
+
console.warn("[StreamSaver] You shouldn't send `data.filename` anymore. It should be included in the Content-Disposition header option")
|
|
100
|
+
// Do what File constructor do with fileNames
|
|
101
|
+
data.filename = data.filename.replace(/\//g, ':')
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** @since v2.0.0 */
|
|
105
|
+
if (data.size) {
|
|
106
|
+
console.warn("[StreamSaver] You shouldn't send `data.size` anymore. It should be included in the content-length header option")
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** @since v2.0.0 */
|
|
110
|
+
if (data.readableStream) {
|
|
111
|
+
console.warn("[StreamSaver] You should send the readableStream in the messageChannel, not throught mitm")
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** @since v2.0.0 */
|
|
115
|
+
if (!data.pathname) {
|
|
116
|
+
console.warn("[StreamSaver] Please send `data.pathname` (eg: /pictures/summer.jpg)")
|
|
117
|
+
data.pathname = Math.random().toString().slice(-6) + '/' + data.filename
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// remove all leading slashes
|
|
121
|
+
data.pathname = data.pathname.replace(/^\/+/g, '')
|
|
122
|
+
|
|
123
|
+
// remove protocol
|
|
124
|
+
let org = origin.replace(/(^\w+:|^)\/\//, '')
|
|
125
|
+
|
|
126
|
+
// set the absolute pathname to the download url.
|
|
127
|
+
data.url = new URL(`${scope + org}/${data.pathname}`).toString()
|
|
128
|
+
|
|
129
|
+
if (!data.url.startsWith(`${scope + org}/`)) {
|
|
130
|
+
throw new TypeError('[StreamSaver] bad `data.pathname`')
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// This sends the message data as well as transferring
|
|
134
|
+
// messageChannel.port2 to the service worker. The service worker can
|
|
135
|
+
// then use the transferred port to reply via postMessage(), which
|
|
136
|
+
// will in turn trigger the onmessage handler on messageChannel.port1.
|
|
137
|
+
|
|
138
|
+
const transferable = data.readableStream
|
|
139
|
+
? [ ports[0], data.readableStream ]
|
|
140
|
+
: [ ports[0] ]
|
|
141
|
+
|
|
142
|
+
if (!(data.readableStream || data.transferringReadable)) {
|
|
143
|
+
keepAlive()
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return sw.postMessage(data, transferable)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (window.opener) {
|
|
150
|
+
// The opener can't listen to onload event, so we need to help em out!
|
|
151
|
+
// (telling them that we are ready to accept postMessage's)
|
|
152
|
+
window.opener.postMessage('StreamSaver::loadedPopup', '*')
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (navigator.serviceWorker) {
|
|
156
|
+
registerWorker().then(() => {
|
|
157
|
+
window.onmessage = onMessage
|
|
158
|
+
messages.forEach(window.onmessage)
|
|
159
|
+
})
|
|
160
|
+
} else {
|
|
161
|
+
// FF can ping sw with fetch from a secure hidden iframe
|
|
162
|
+
// shouldn't really be possible?
|
|
163
|
+
keepAlive()
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
</script>
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/* global self ReadableStream Response */
|
|
2
|
+
|
|
3
|
+
self.addEventListener('install', () => {
|
|
4
|
+
self.skipWaiting()
|
|
5
|
+
})
|
|
6
|
+
|
|
7
|
+
self.addEventListener('activate', event => {
|
|
8
|
+
event.waitUntil(self.clients.claim())
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
const map = new Map()
|
|
12
|
+
|
|
13
|
+
// This should be called once per download
|
|
14
|
+
// Each event has a dataChannel that the data will be piped through
|
|
15
|
+
self.onmessage = event => {
|
|
16
|
+
// We send a heartbeat every x secound to keep the
|
|
17
|
+
// service worker alive if a transferable stream is not sent
|
|
18
|
+
if (event.data === 'ping') {
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const data = event.data
|
|
23
|
+
const downloadUrl = data.url || self.registration.scope + Math.random() + '/' + (typeof data === 'string' ? data : data.filename)
|
|
24
|
+
const port = event.ports[0]
|
|
25
|
+
const metadata = new Array(3) // [stream, data, port]
|
|
26
|
+
|
|
27
|
+
metadata[1] = data
|
|
28
|
+
metadata[2] = port
|
|
29
|
+
|
|
30
|
+
// Note to self:
|
|
31
|
+
// old streamsaver v1.2.0 might still use `readableStream`...
|
|
32
|
+
// but v2.0.0 will always transfer the stream throught MessageChannel #94
|
|
33
|
+
if (event.data.readableStream) {
|
|
34
|
+
metadata[0] = event.data.readableStream
|
|
35
|
+
} else if (event.data.transferringReadable) {
|
|
36
|
+
port.onmessage = evt => {
|
|
37
|
+
port.onmessage = null
|
|
38
|
+
metadata[0] = evt.data.readableStream
|
|
39
|
+
}
|
|
40
|
+
} else {
|
|
41
|
+
metadata[0] = createStream(port)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
map.set(downloadUrl, metadata)
|
|
45
|
+
port.postMessage({ download: downloadUrl })
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function createStream (port) {
|
|
49
|
+
// ReadableStream is only supported by chrome 52
|
|
50
|
+
return new ReadableStream({
|
|
51
|
+
start (controller) {
|
|
52
|
+
// When we receive data on the messageChannel, we write
|
|
53
|
+
port.onmessage = ({ data }) => {
|
|
54
|
+
if (data === 'end') {
|
|
55
|
+
return controller.close()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (data === 'abort') {
|
|
59
|
+
controller.error('Aborted the download')
|
|
60
|
+
return
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
controller.enqueue(data)
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
cancel () {
|
|
67
|
+
console.log('user aborted')
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
self.onfetch = event => {
|
|
73
|
+
const url = event.request.url
|
|
74
|
+
|
|
75
|
+
// this only works for Firefox
|
|
76
|
+
if (url.endsWith('/ping')) {
|
|
77
|
+
return event.respondWith(new Response('pong'))
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const hijacke = map.get(url)
|
|
81
|
+
|
|
82
|
+
if (!hijacke) return null
|
|
83
|
+
|
|
84
|
+
const [ stream, data, port ] = hijacke
|
|
85
|
+
|
|
86
|
+
map.delete(url)
|
|
87
|
+
|
|
88
|
+
// Not comfortable letting any user control all headers
|
|
89
|
+
// so we only copy over the length & disposition
|
|
90
|
+
const responseHeaders = new Headers({
|
|
91
|
+
'Content-Type': 'application/octet-stream; charset=utf-8',
|
|
92
|
+
|
|
93
|
+
// To be on the safe side, The link can be opened in a iframe.
|
|
94
|
+
// but octet-stream should stop it.
|
|
95
|
+
'Content-Security-Policy': "default-src 'none'",
|
|
96
|
+
'X-Content-Security-Policy': "default-src 'none'",
|
|
97
|
+
'X-WebKit-CSP': "default-src 'none'",
|
|
98
|
+
'X-XSS-Protection': '1; mode=block'
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
let headers = new Headers(data.headers || {})
|
|
102
|
+
|
|
103
|
+
if (headers.has('Content-Length')) {
|
|
104
|
+
responseHeaders.set('Content-Length', headers.get('Content-Length'))
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (headers.has('Content-Disposition')) {
|
|
108
|
+
responseHeaders.set('Content-Disposition', headers.get('Content-Disposition'))
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// data, data.filename and size should not be used anymore
|
|
112
|
+
if (data.size) {
|
|
113
|
+
console.warn('Depricated')
|
|
114
|
+
responseHeaders.set('Content-Length', data.size)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
let fileName = typeof data === 'string' ? data : data.filename
|
|
118
|
+
if (fileName) {
|
|
119
|
+
console.warn('Depricated')
|
|
120
|
+
// Make filename RFC5987 compatible
|
|
121
|
+
fileName = encodeURIComponent(fileName).replace(/['()]/g, escape).replace(/\*/g, '%2A')
|
|
122
|
+
responseHeaders.set('Content-Disposition', "attachment; filename*=UTF-8''" + fileName)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
event.respondWith(new Response(stream, { headers: responseHeaders }))
|
|
126
|
+
|
|
127
|
+
port.postMessage({ debug: 'Download started' })
|
|
128
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export declare type ResponseType = 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream';
|
|
2
|
+
/**
|
|
3
|
+
* Get服务请求
|
|
4
|
+
* @param apiUrl API接口路径
|
|
5
|
+
* @param baseUrl 基础服务路径
|
|
6
|
+
* @param _params 参数
|
|
7
|
+
* @param headers headers参数
|
|
8
|
+
* @param responseType 响应类型,默认为json
|
|
9
|
+
* @param cancelToken 取消标识
|
|
10
|
+
* @returns 返回Promise对象
|
|
11
|
+
*/
|
|
12
|
+
declare function requestGet(apiUrl: string, baseUrl?: string, _params?: any, headers?: any, responseType?: ResponseType, cancelToken?: any): Promise<any>;
|
|
13
|
+
/**
|
|
14
|
+
* Post服务请求-FormData
|
|
15
|
+
* @param apiUrl API接口路径
|
|
16
|
+
* @param baseUrl 基础服务路径
|
|
17
|
+
* @param _params 参数
|
|
18
|
+
* @param headers headers参数
|
|
19
|
+
* @returns 返回Promise对象
|
|
20
|
+
*/
|
|
21
|
+
declare function requestPost(apiUrl: string, baseUrl?: string, _bodyParams?: any, _queryParams?: any, headers?: any, responseType?: ResponseType): Promise<any>;
|
|
22
|
+
/**
|
|
23
|
+
* Post服务请求-Body方式
|
|
24
|
+
* @param apiUrl API接口路径
|
|
25
|
+
* @param baseUrl 基础服务路径
|
|
26
|
+
* @param _params 参数
|
|
27
|
+
* @returns 返回Promise对象
|
|
28
|
+
*/
|
|
29
|
+
declare function requestPostBody(apiUrl: string, baseUrl?: string, _bodyParams?: any, _queryParams?: any, headers?: any, responseType?: ResponseType): Promise<any>;
|
|
30
|
+
/**
|
|
31
|
+
* 业务服务Get请求
|
|
32
|
+
* @param apiUrl API接口路径
|
|
33
|
+
* @param _params 参数
|
|
34
|
+
* @returns 返回Promise对象
|
|
35
|
+
*/
|
|
36
|
+
declare function get(apiUrl: string, _params?: any): Promise<any>;
|
|
37
|
+
/**
|
|
38
|
+
* 业务服务Post请求
|
|
39
|
+
* @param apiUrl API接口路径
|
|
40
|
+
* @param _params 参数
|
|
41
|
+
* @returns 返回Promise对象
|
|
42
|
+
*/
|
|
43
|
+
declare function post(apiUrl: string, _params?: any): Promise<any>;
|
|
44
|
+
/**
|
|
45
|
+
* 独立的外部Get请求(无token验证信息)
|
|
46
|
+
* @param fullRequestURL 完整请求路径
|
|
47
|
+
* @param _params 请求参数
|
|
48
|
+
* @returns 返回Promise对象
|
|
49
|
+
*/
|
|
50
|
+
declare function getData(fullRequestURL: string, _params?: any): Promise<any>;
|
|
51
|
+
export { get, post, requestPost, requestGet, getData, requestPostBody };
|