weboffice-js-sdk 2.0.2 → 2.0.3-beta.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 +493 -0
- package/{OfficeSDK.d.ts → dist/OfficeSDK.d.ts} +111 -5
- package/{index.d.ts → dist/index.d.ts} +2 -0
- package/dist/index.js +2 -0
- package/dist/types/EmptyPage.d.ts +120 -0
- package/package.json +55 -5
- package/assets/loading.d.ts +0 -1
- package/index.js +0 -1
- /package/{assert.d.ts → dist/assert.d.ts} +0 -0
- /package/{connect.d.ts → dist/connect.d.ts} +0 -0
- /package/{types → dist/types}/BaseEditor.d.ts +0 -0
- /package/{types → dist/types}/Document.d.ts +0 -0
- /package/{types → dist/types}/DocumentPro.d.ts +0 -0
- /package/{types → dist/types}/FlowChart.d.ts +0 -0
- /package/{types → dist/types}/Form.d.ts +0 -0
- /package/{types → dist/types}/Presentation.d.ts +0 -0
- /package/{types → dist/types}/Spreadsheet.d.ts +0 -0
- /package/{types → dist/types}/Table.d.ts +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
# 石墨 JS SDK
|
|
2
|
+
|
|
3
|
+
此 SDK 对应石墨 SDK 2.0 产品,目的是让石墨 SDK 2.0 产品的客户能够快速接入 SDK,并和石墨文档套件进行前端交互。
|
|
4
|
+
|
|
5
|
+
关于石墨 SDK 2.0 产品的详细内容请移步 [SDK 2.0 官网](https://platform.shimo.im/v2/)。
|
|
6
|
+
|
|
7
|
+
_注:此 SDK 无法用于石墨文档官网产品 (即 shimo.im) 。_
|
|
8
|
+
|
|
9
|
+
## [文档详情](https://shimo-open.github.io/shimo-js-sdk/#/)
|
|
10
|
+
|
|
11
|
+
### 安装
|
|
12
|
+
|
|
13
|
+
```shell
|
|
14
|
+
# 通过 npm
|
|
15
|
+
npm install --save shimo-js-sdk
|
|
16
|
+
|
|
17
|
+
# 通过 yarn
|
|
18
|
+
yarn add shimo-js-sdk
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### 初始化 iframe
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
const { connect } = require('shimo-js-sdk')
|
|
25
|
+
|
|
26
|
+
connect({
|
|
27
|
+
fileId: '您系统中的 file id',
|
|
28
|
+
endpoint: '石墨服务的地址',
|
|
29
|
+
signature: '用您的 app id 和 secret 签发的签名',
|
|
30
|
+
token: '用于您系统识别用户请求的 token',
|
|
31
|
+
container: document.querySelector('#shimo-file'), // iframe 挂载的目标容器元素
|
|
32
|
+
lang: 'en' // 未指定此参数时,使用浏览器默认语言
|
|
33
|
+
userUuid:'您的uuid', // 仅在v2版本回调时需要传入(co-1.3+支持)
|
|
34
|
+
}).then((shimoSDK) => {
|
|
35
|
+
// ...
|
|
36
|
+
})
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
参数说明请参考 [docs/interfaces/connectoptions.md](docs/interfaces/ConnectOptions.md)。
|
|
40
|
+
|
|
41
|
+
返回值:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
Promise<ShimoSDK>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**使用传统的 `<script>` 的方式加载:**
|
|
48
|
+
|
|
49
|
+
1. 使用 [npm view](https://docs.npmjs.com/cli/v7/commands/npm-view) 和 [npm pack](https://docs.npmjs.com/cli/v7/commands/npm-pack) 下载代码包 (`.tgz` 格式)
|
|
50
|
+
2. 将 `.tgz` 解压缩后的 `dist` 目录下的文件放置到您托管静态资源的空间,然后使用 `<script>` 引入 `index.js` 资源
|
|
51
|
+
3. 通过 `window.ShimoJSSDK` 对象获取对应的方法
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
const { connect, FileType } = window.ShimoJSSDK
|
|
55
|
+
// 等价于
|
|
56
|
+
const { connect, FileType } = require('shimo-js-sdk')
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
#### 使用示例
|
|
60
|
+
|
|
61
|
+
```js
|
|
62
|
+
const { connect } = require('shimo-js-sdk')
|
|
63
|
+
|
|
64
|
+
const fileId = '1234'
|
|
65
|
+
const uuid = 'youruuid'
|
|
66
|
+
|
|
67
|
+
// 从您的后端服务获取用于石墨鉴权的签名和 token
|
|
68
|
+
const { signature, token } = await getCredentialsFromServer()
|
|
69
|
+
|
|
70
|
+
connect({
|
|
71
|
+
fileId: fileId,
|
|
72
|
+
endpoint: 'https://shimo-sdk-endpoint/', // endpoint 因环境而异,请联系技术支持
|
|
73
|
+
signature: signature,
|
|
74
|
+
token: token,
|
|
75
|
+
container: document.querySelector('#shimo-file'), // iframe 挂载的目标容器元素
|
|
76
|
+
userUuid: uuid
|
|
77
|
+
}).then((sdk) => {
|
|
78
|
+
// sdk 即为 ShimoSDK 实例
|
|
79
|
+
})
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
调用 `connect()` 时,会以传入参数为基础,初始化一个 `<iframe>` 并插入 `container` 对应的元素中。
|
|
83
|
+
|
|
84
|
+
返回的 `sdk` 为 `ShimoSDK` 实例,用于和 SDK、编辑器交互。
|
|
85
|
+
|
|
86
|
+
### SDK 和编辑器实例
|
|
87
|
+
|
|
88
|
+
石墨 JS SDK 共有两种实例用于和 JS SDK 交互:
|
|
89
|
+
|
|
90
|
+
- `ShimoSDK` 由 `connect()` 返回,处理初始化编辑器和编辑器交互的工作
|
|
91
|
+
- `Editor` 文档编辑器,直接和文档内容交互。**`Editor` 所有接口均返回 Promise**
|
|
92
|
+
|
|
93
|
+
两者之间各有独立的方法和事件,具体请查看 `docs` 目录的文档。
|
|
94
|
+
|
|
95
|
+
获取编辑器实例和与其交互:
|
|
96
|
+
|
|
97
|
+
```js
|
|
98
|
+
const { FileType } = require('shimo-js-sdk')
|
|
99
|
+
|
|
100
|
+
// 获取编辑器实例
|
|
101
|
+
const editor = sdk.getEditor()
|
|
102
|
+
|
|
103
|
+
// 调用通用事件
|
|
104
|
+
editor.on('saveStatusChanged', (payload) => {
|
|
105
|
+
console.log(payload.status)
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
// 调用特定类型文档的方法
|
|
109
|
+
if (sdk.fileType === FileType.Document) {
|
|
110
|
+
editor.showHistory()
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
若为 `TypeScript`,可使用 `Generic`:
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
const { Document } = require('shimo-js-sdk')
|
|
118
|
+
|
|
119
|
+
const editor = sdk.getEditor<Document.Editor>()
|
|
120
|
+
editor.on('saveStatusChanged', (payload) => {
|
|
121
|
+
console.log(payload.status)
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
await editor.showHistory()
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### HeaderBars 使用说明
|
|
128
|
+
|
|
129
|
+
`sdk.headerBars` 提供显式 facade,不依赖 editor Proxy 路径猜测能力。
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
const sdk = await connect(options)
|
|
133
|
+
|
|
134
|
+
// 顶栏显示状态(属性读写)
|
|
135
|
+
sdk.headerBars.visible = false
|
|
136
|
+
await sdk.headerBars.setVisible(true)
|
|
137
|
+
|
|
138
|
+
// 命令增删改查
|
|
139
|
+
await sdk.headerBars.addCommand(
|
|
140
|
+
{ id: 'custom-export', section: 'more' },
|
|
141
|
+
'download'
|
|
142
|
+
)
|
|
143
|
+
const command = sdk.headerBars.getCommand('custom-export')
|
|
144
|
+
|
|
145
|
+
// 命令状态(属性读写)
|
|
146
|
+
command.visible = true
|
|
147
|
+
command.disabled = false
|
|
148
|
+
|
|
149
|
+
// 外层覆盖命令点击回调(优先于 iframe 默认回调)
|
|
150
|
+
command.onCommandClick = async () => {
|
|
151
|
+
console.log('custom-export clicked')
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### 协作者模块使用说明
|
|
156
|
+
|
|
157
|
+
当 iframe 套件开启协作者能力后(依赖 `ENABLE_SDK_COLLABORATORS_MODULE` 开关),shimo-js-sdk 使用方可按以下方式接入:
|
|
158
|
+
|
|
159
|
+
1. **监听 `collaboratorsChanged`**
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
const sdk = await connect(options)
|
|
163
|
+
const editor = sdk.getEditor()
|
|
164
|
+
|
|
165
|
+
editor.on('collaboratorsChanged', (payload) => {
|
|
166
|
+
// payload.type: 'snapshot' | 'enter' | 'leave'
|
|
167
|
+
// payload.collaborators: 协作者全量列表
|
|
168
|
+
renderCollaborators(payload)
|
|
169
|
+
|
|
170
|
+
if (payload.type === 'enter') {
|
|
171
|
+
console.log('新协作者进入:', payload.enterUsers)
|
|
172
|
+
} else if (payload.type === 'leave') {
|
|
173
|
+
console.log('协作者离开:', payload.leaveUsers)
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
3. **主动获取协作者列表**
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
const collaborators = editor.getCollaborators()
|
|
182
|
+
renderCollaborators({ type: 'snapshot', collaborators })
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
4. **调试提示**
|
|
186
|
+
- 未收到事件时,检查 iframe 内的 window 对象是否有 `window.__RUNTIME_ENV__.ENABLE_SDK_COLLABORATORS_MODULE` 属性且为 true。
|
|
187
|
+
- 可在 iframe 页面 DevTools 中查看 `collaboratorsChanged` 是否触发,或观察 WebSocket `COLLABROOM` 消息。
|
|
188
|
+
|
|
189
|
+
### 「系统已禁止编辑」确认回调
|
|
190
|
+
|
|
191
|
+
当 iframe 内因为 `STATUS_FORBIDDEN` 弹出“系统已禁止编辑”提示后,用户点击确认按钮,会额外派发一个 `editForbiddenConfirmed` 编辑器事件:
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
editor.on('editForbiddenConfirmed', ({ reason }) => {
|
|
195
|
+
if (reason === 'STATUS_FORBIDDEN') {
|
|
196
|
+
// 执行 iframe 外层自己的确认回调
|
|
197
|
+
}
|
|
198
|
+
})
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### `signature` 和 `token`
|
|
202
|
+
|
|
203
|
+
- `signature` 为石墨区分请求来源,并实现数据隔离的基础
|
|
204
|
+
- `token` 为您用于识别回调请求来源、是否合法的依据
|
|
205
|
+
|
|
206
|
+
具体说明请查阅在线文档:[https://platform.shimo.im/v2/docs/concepts/](https://platform.shimo.im/v2/docs/concepts/)。
|
|
207
|
+
|
|
208
|
+
由于 `signature` 和 `token` 有过期时间,一般也不建议设置过长的时间,但为了减少因过期导致的用户体验问题,`ShimoSDK` 提供 `setCredentials({ signature, token })` 方法用于动态更新。
|
|
209
|
+
|
|
210
|
+
```js
|
|
211
|
+
/**
|
|
212
|
+
* 从您的后端服务获取用于石墨鉴权的签名和 token
|
|
213
|
+
* @deprecated
|
|
214
|
+
*/
|
|
215
|
+
let { signature, token, expires } = await getCredentialsFromServer()
|
|
216
|
+
|
|
217
|
+
const shimoSDK = await connect({ ... })
|
|
218
|
+
|
|
219
|
+
setInterval(
|
|
220
|
+
() => {
|
|
221
|
+
// 建议过期时间为7天
|
|
222
|
+
// 当剩余时间不到3.5天就过期时进行更新
|
|
223
|
+
if (expires - Date.now() < 1000 * 3600 * 24 * 3.5) {
|
|
224
|
+
const resp = await getCredentialsFromServer()
|
|
225
|
+
await shimoSDK.setCredentials({
|
|
226
|
+
signature: resp.signature,
|
|
227
|
+
token: resp.token
|
|
228
|
+
})
|
|
229
|
+
expires = resp.expires
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
60 * 1000
|
|
233
|
+
)
|
|
234
|
+
// 以上为旧版本更新鉴权方式,新版本(v1.2.23+)请参照如下方式进行更新
|
|
235
|
+
const shimoSDK = await connect({
|
|
236
|
+
signature: '[your signature]',
|
|
237
|
+
token: '[your token]',
|
|
238
|
+
// 更新鉴权的时间间隔,单位为毫秒
|
|
239
|
+
// 若过期时间为7天,则建议设置为1000 * 3600 * 24 * 3.5 (3.5天)
|
|
240
|
+
refreshCredentialsInterval: 1000 * 3600 * 24 * 3.5,
|
|
241
|
+
getCredentials: async () => {
|
|
242
|
+
const res = await getCredentialsFromServer()
|
|
243
|
+
return {
|
|
244
|
+
signature: res.signature,
|
|
245
|
+
token: res.token,
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
})
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### 如何处理 URL
|
|
252
|
+
|
|
253
|
+
由于石墨 SDK 以 `iframe` 的形式挂载到当前页面,`iframe.src` 对应的 URL 并不适合用于分享,而且在一些功能上,比如 @ 文件,需要用到您系统中对应的 URL 格式,比如 `https://your-domain/files/:id`。
|
|
254
|
+
|
|
255
|
+
为了解决这个问题,石墨 SDK 引入 `generateUrl()` 和 `openLink()` 方法:
|
|
256
|
+
|
|
257
|
+
```js
|
|
258
|
+
import { UrlSharingType } from 'shimo-js-sdk'
|
|
259
|
+
|
|
260
|
+
const shimoSDK = await connect({
|
|
261
|
+
...,
|
|
262
|
+
|
|
263
|
+
generateUrl(fileId: string, info: GenerateUrlInfo): string {
|
|
264
|
+
if (info?.sharingType === UrlSharingType.FormFill) {
|
|
265
|
+
return `https://your-domain/files/${fileId}/fill-form`
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (info?.sharingText) {
|
|
269
|
+
return `https://your-domain/files/${fileId} ${info.sharingText}`
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return `https://your-domain/files/${fileId}`
|
|
273
|
+
},
|
|
274
|
+
|
|
275
|
+
openLink(url: string): void {
|
|
276
|
+
// 以 React Router 为例
|
|
277
|
+
|
|
278
|
+
// 假设 url 是 'https://your-domain/files/1',在当前页跳转,其他则新窗口打开
|
|
279
|
+
if (url.includes('your-domain/files/')) {
|
|
280
|
+
const u = new URL(url)
|
|
281
|
+
history.push(u.pathname)
|
|
282
|
+
} else {
|
|
283
|
+
window.open(url)
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
|
|
287
|
+
// 从当前 url 中解析出文件 id 并返回
|
|
288
|
+
// 假设 url 是 'https://your-domain/files/123',则返回 { fileId: '123' }
|
|
289
|
+
getFileInfoFromUrl(url: string): {fileId:string} {
|
|
290
|
+
let fromId
|
|
291
|
+
const urlWithoutParams = url.split('?')[0]
|
|
292
|
+
let splitPath = urlWithoutParams.split('/')
|
|
293
|
+
fromId = splitPath[splitPath.length - 1]
|
|
294
|
+
return Promise.resolve({
|
|
295
|
+
fileId: fromId
|
|
296
|
+
})
|
|
297
|
+
}
|
|
298
|
+
})
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
#### URL 的上下文信息
|
|
302
|
+
|
|
303
|
+
为了在 URL 上传递上下文信息,比如 URL 指向的段落、单元格,在调用 `generateUrl()` 生成 URL 后,会在 URL 后附加一个 `smParams=PARAMS` 的参数:
|
|
304
|
+
|
|
305
|
+
```
|
|
306
|
+
https://your-domain/files/:id?smParams=PARAMS
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
**如无特殊需要,请保留该参数。**
|
|
310
|
+
|
|
311
|
+
默认情况下,调用 `connect()` 会从当前 `location.search` 中提取 `smParams`,如果遇到需要自定义参数的场合,可以通过 `connect({ smParams: PARAMS })` 参数修改。
|
|
312
|
+
|
|
313
|
+
`smParams` 为经过 [base62](https://github.com/felipecarrillo100/base62str) 序列化后的 `Record<string, unknown>` 对象。
|
|
314
|
+
|
|
315
|
+
**在传入 `smParams` 参数时,将不会从 `location.search` 中获取数据**,如果想保留原有信息,可以这样传递:
|
|
316
|
+
|
|
317
|
+
```js
|
|
318
|
+
const paramsList: Array<string | Record<string, unknown>>
|
|
319
|
+
|
|
320
|
+
const originParams = new URLSearchParams(location.search).get('smParams')
|
|
321
|
+
// 保留原来的上下文信息
|
|
322
|
+
if (originParams) {
|
|
323
|
+
paramsList.push(originParams)
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// 添加自定义的上下文信息
|
|
327
|
+
paramsList.push({
|
|
328
|
+
myVar: 'myVal'
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
connect({
|
|
332
|
+
smParams: paramsList
|
|
333
|
+
})
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
#### URL Info
|
|
337
|
+
|
|
338
|
+
`generateUrl(fileId, info)` 中的 `info` 是用于对 URL 进行一些特殊处理的。
|
|
339
|
+
|
|
340
|
+
`sharingText`:石墨默认提供的分享文本:比如
|
|
341
|
+
|
|
342
|
+
- `https://your-domain/files/1 xxx 邀请您参与《标题》协作,请复制粘贴后在浏览器打开`
|
|
343
|
+
- `https://your-domain/files/1/fill-form xxx 邀请您填写《标题》表单,……`
|
|
344
|
+
|
|
345
|
+
`sharingType`:表示此次 `generateUrl()` 对应的行为类型,比如:
|
|
346
|
+
|
|
347
|
+
- `UrlSharingType.Form` 代表一般的打开编辑表单的行为
|
|
348
|
+
- `UrlSharingType.FormPreview` 代表打开预览表单页面的行为
|
|
349
|
+
- `UrlSharingType.FormFill` 代表打开填写表单页面的行为
|
|
350
|
+
|
|
351
|
+
您需要根据具体类型,生成不同的 URL,比如:
|
|
352
|
+
|
|
353
|
+
- `UrlSharingType.Form`、`UrlSharingType.FormPreview` 等一般需要进行鉴权,因此可以用 `/files/${fileId}`
|
|
354
|
+
- `UrlSharingType.FormFill` 填写表单一般不需要登录鉴权,因此可以用另一个独立的路由,比如 `/files/${fileId}/fill-form`
|
|
355
|
+
|
|
356
|
+
在实际操作中,您可以根据 `sharingType` 按需为 URL 添加分享文本。**若添加了分享文本,则需要您在 `parseUrl()` 中对 URL 进行处理**,比如:
|
|
357
|
+
|
|
358
|
+
```js
|
|
359
|
+
// url: 'https://your-domain/files/1 xxx 邀请您参与《标题》协作,请复制粘贴后在浏览器打开'
|
|
360
|
+
parseUrl(url: string) {
|
|
361
|
+
return url.split(' ')[0] // 返回 'https://your-domain/files/1
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### 打开表格编辑器时展示指定工作表 (Sheet)
|
|
366
|
+
|
|
367
|
+
**使用本章节用法时,请先了解 [URL 的上下文信息](#url-的上下文信息) 章节**。
|
|
368
|
+
|
|
369
|
+
此用法适用于表格中存在多个工作表 (Sheet) ,希望在打开编辑器时,直接展示某个工作表格而非默认的第一个工作表。如用于希望直接分享表格的某个工作表链接给其他协作者,他人在打开后可直接查看指定的工作表。
|
|
370
|
+
|
|
371
|
+
首先通过 `docs/interfaces/Spreadsheet.Editor.md` 表格的编辑器 `getActiveSheetId` 方法获取当前处于激活状态的工作表 ID ,此 ID 可用于追加在接入方自身的 URL 上作为参数。
|
|
372
|
+
|
|
373
|
+
如通过 `URL QueryString` 方式传递:`https://your-domain.com/files/abcdefg?sheetId=XXXXX&smParams=XXXXXXXXXXXXXXXXXXXXXX`
|
|
374
|
+
|
|
375
|
+
`sheetId` 仅为参数名举例,接入方可结合自身业务命名。
|
|
376
|
+
|
|
377
|
+
```js
|
|
378
|
+
const paramsList: Array<string | Record<string, unknown>>
|
|
379
|
+
const queryParams = new URLSearchParams(location.search)
|
|
380
|
+
|
|
381
|
+
const originParams = queryParams.get('smParams')
|
|
382
|
+
const sheetId = queryParams.get('sheetId')
|
|
383
|
+
|
|
384
|
+
// 保留原来的上下文信息
|
|
385
|
+
if (originParams) {
|
|
386
|
+
paramsList.push(originParams)
|
|
387
|
+
}
|
|
388
|
+
// paramsList
|
|
389
|
+
// => [originParamsStringValue]
|
|
390
|
+
|
|
391
|
+
// 添加自定义的上下文信息
|
|
392
|
+
paramsList.push({ sheetId: '通过 QueryString 中获取的 sheetId' })
|
|
393
|
+
// paramsList
|
|
394
|
+
// => [originParamsStringValue, {"sheetId": "XXXXX"}]
|
|
395
|
+
|
|
396
|
+
connect({
|
|
397
|
+
smParams: paramsList
|
|
398
|
+
})
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### 打开编辑器时,定位至在正文中 at 某用户或评论的位置
|
|
402
|
+
|
|
403
|
+
支持类型:
|
|
404
|
+
|
|
405
|
+
- `轻文档` - `document`
|
|
406
|
+
- `表格` - `spreadsheet`
|
|
407
|
+
- `传统文档` - `documentPro`
|
|
408
|
+
|
|
409
|
+
**使用本章节用法时,请先了解 [URL 的上下文信息](#url-的上下文信息) 章节**。
|
|
410
|
+
|
|
411
|
+
此用法适用于:
|
|
412
|
+
|
|
413
|
+
- 定位@用户: 在接入方系统的文件中 at 了指定用户,在回调接口中收到 `石墨 SDK 事件` 中的 `mention_at` 类型事件,并获取 `mentionAt.guid` 字段作为参数拼接至接入方的访问链接上,在接入方系统通知对应用户时,推送的链接可直接打开对应文件并定位至当前用户被 at 的正文位置,以便于查看对应位置相关内容。
|
|
414
|
+
- 新增评论: 在接入方系统的文件中新增了评论,在回调接口中收到 `石墨 SDK 事件` 中的 `comment` 类型事件,并获取 `comment.selectionGuid` 字段作为参数拼接至接入方的访问链接上,在接入方系统通知对应用户时,推送的链接可直接打开对应文件并定位至当前新增的评论位置,以便于查看对应位置相关内容。
|
|
415
|
+
|
|
416
|
+
如通过 `URL QueryString` 方式传递:`https://your-domain.com/files/abcdefg?mentionId=XXXXX&smParams=XXXXXXXXXXXXXXXXXXXXXX`
|
|
417
|
+
|
|
418
|
+
`mentionId` 仅为参数名举例,接入方可结合自身业务命名。
|
|
419
|
+
|
|
420
|
+
```js
|
|
421
|
+
const paramsList: Array<string | Record<string, unknown>>
|
|
422
|
+
const queryParams = new URLSearchParams(location.search)
|
|
423
|
+
|
|
424
|
+
const originParams = queryParams.get('smParams')
|
|
425
|
+
const mentionId = queryParams.get('mentionId')
|
|
426
|
+
|
|
427
|
+
// 保留原来的上下文信息
|
|
428
|
+
if (originParams) {
|
|
429
|
+
paramsList.push(originParams)
|
|
430
|
+
}
|
|
431
|
+
// paramsList
|
|
432
|
+
// => [originParamsStringValue]
|
|
433
|
+
|
|
434
|
+
// 添加自定义的上下文信息
|
|
435
|
+
paramsList.push({ hash: '通过 QueryString 中获取的 mentionId' })
|
|
436
|
+
// paramsList
|
|
437
|
+
// => [originParamsStringValue, {"hash": "XXXXX"}]
|
|
438
|
+
|
|
439
|
+
connect({
|
|
440
|
+
smParams: paramsList
|
|
441
|
+
})
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### 覆盖编辑器内置 toast 文案
|
|
445
|
+
|
|
446
|
+
支持的套件类型:
|
|
447
|
+
|
|
448
|
+
- `表单` - `form`
|
|
449
|
+
- `传统文档` - `documentPro`
|
|
450
|
+
- `专业幻灯片` - `presentation`
|
|
451
|
+
- `表格` - `spreadsheet`
|
|
452
|
+
- `应用表格` - `table`
|
|
453
|
+
|
|
454
|
+
仅对支持 `ui` 配置的套件生效。
|
|
455
|
+
|
|
456
|
+
当前已文档化支持字段:
|
|
457
|
+
|
|
458
|
+
- `ui.toast.tips.edit.noPermission`
|
|
459
|
+
|
|
460
|
+
```typescript
|
|
461
|
+
import { connect } from 'shimo-js-sdk'
|
|
462
|
+
|
|
463
|
+
const shimoSDK = await connect({
|
|
464
|
+
ui: {
|
|
465
|
+
toast: {
|
|
466
|
+
tips: {
|
|
467
|
+
edit: {
|
|
468
|
+
noPermission: '你没有编辑权限'
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
})
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### 显示自定义 toast
|
|
477
|
+
|
|
478
|
+
支持的套件类型:
|
|
479
|
+
|
|
480
|
+
- `表格` - `spreadsheet`
|
|
481
|
+
|
|
482
|
+
此方法可显示接入方自定义 toast,具体用法如下
|
|
483
|
+
|
|
484
|
+
```typescript
|
|
485
|
+
import { connect, ShowToastOptions } from 'shimo-js-sdk'
|
|
486
|
+
|
|
487
|
+
const shimoSDK = await connect({
|
|
488
|
+
// 初始化sdk时传了该方法将会拦截编辑器内的toast
|
|
489
|
+
showToast: (options: ShowToastOptions) => {
|
|
490
|
+
// show your toast
|
|
491
|
+
}
|
|
492
|
+
})
|
|
493
|
+
```
|
|
@@ -6,7 +6,42 @@ import 'proxy-polyfill';
|
|
|
6
6
|
import { TinyEmitter } from 'tiny-emitter';
|
|
7
7
|
import { ContainerMethod, ContainerRect, DisableMentionCards, FileType, InvokeMethod, MouseMovePayload, ReadyState, PerformanceEntry, DeviceMode, GenerateUrlHandler, APIAdaptor, RequestContext, ShowToastOptions, Credentials } from 'weboffice-js-sdk-shared';
|
|
8
8
|
import { Document, DocumentPro, Presentation, Spreadsheet, Table, Form, Flowchart } from '.';
|
|
9
|
+
import { EmptyPageOptions } from './types/EmptyPage';
|
|
9
10
|
import { BaseEditor } from './types/BaseEditor';
|
|
11
|
+
export interface HeaderBarsCommandDefinition {
|
|
12
|
+
id: string;
|
|
13
|
+
section?: string;
|
|
14
|
+
order?: number;
|
|
15
|
+
label?: string;
|
|
16
|
+
visible?: boolean;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
editable?: boolean;
|
|
19
|
+
type?: 'action' | 'structural';
|
|
20
|
+
renderType?: string;
|
|
21
|
+
src?: string;
|
|
22
|
+
onClick?: () => void | Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
export interface HeaderBarsCommandState extends HeaderBarsCommandDefinition {
|
|
25
|
+
type: 'action' | 'structural';
|
|
26
|
+
}
|
|
27
|
+
export interface HeaderBarsCommandRef {
|
|
28
|
+
readonly id: string;
|
|
29
|
+
visible: boolean;
|
|
30
|
+
disabled: boolean;
|
|
31
|
+
editable?: boolean;
|
|
32
|
+
onCommandClick?: () => void | Promise<void>;
|
|
33
|
+
getState: () => HeaderBarsCommandState | undefined;
|
|
34
|
+
}
|
|
35
|
+
export interface HeaderBarsFacade {
|
|
36
|
+
visible: boolean;
|
|
37
|
+
getVisible: () => Promise<boolean>;
|
|
38
|
+
setVisible: (visible: boolean) => Promise<void>;
|
|
39
|
+
addCommand: (command: HeaderBarsCommandDefinition, posCommand: string, pos?: 'before' | 'after') => Promise<boolean>;
|
|
40
|
+
getCommand: (id: string) => HeaderBarsCommandRef;
|
|
41
|
+
listViewCommands: () => Promise<HeaderBarsCommandState[]>;
|
|
42
|
+
setTitleDraft: (title: string) => Promise<void>;
|
|
43
|
+
confirmTitleChange: (title: string) => Promise<void>;
|
|
44
|
+
}
|
|
10
45
|
export declare const MessageEvent: typeof InvokeMethod;
|
|
11
46
|
export declare class OfficeSDK extends TinyEmitter {
|
|
12
47
|
/**
|
|
@@ -50,9 +85,9 @@ export declare class OfficeSDK extends TinyEmitter {
|
|
|
50
85
|
* @deprecated - 用 `sdk.getEditor<T>()` 替代
|
|
51
86
|
*/
|
|
52
87
|
flowchart?: Flowchart.Editor;
|
|
88
|
+
readonly headerBars: HeaderBarsFacade;
|
|
53
89
|
private _fileType;
|
|
54
90
|
private readonly messageHandler;
|
|
55
|
-
private loadingOverlay?;
|
|
56
91
|
/**
|
|
57
92
|
* 内部 event emitter,比如用来中转 editor 事件
|
|
58
93
|
*/
|
|
@@ -75,7 +110,18 @@ export declare class OfficeSDK extends TinyEmitter {
|
|
|
75
110
|
*/
|
|
76
111
|
private readonly endpoint;
|
|
77
112
|
private readonly sameOrigin;
|
|
113
|
+
private headerBarsVisible;
|
|
114
|
+
private readonly headerBarsCommands;
|
|
115
|
+
private readonly headerBarsCommandOverrides;
|
|
116
|
+
private readonly headerBarsCommandRefs;
|
|
78
117
|
private readonly onViewportResize;
|
|
118
|
+
/**
|
|
119
|
+
* 归一化后的缺省页配置,构造时一次算完,后续仅读取。
|
|
120
|
+
*/
|
|
121
|
+
private readonly normalizedEmptyPage;
|
|
122
|
+
private readonly preloadAckTimeoutMs;
|
|
123
|
+
private readonly preloadDoneTimeoutMs;
|
|
124
|
+
private readonly preloadReadyTimeoutMs;
|
|
79
125
|
constructor(options: OfficeSDKOptions);
|
|
80
126
|
get fileType(): FileType;
|
|
81
127
|
get readyState(): ReadyState;
|
|
@@ -110,15 +156,20 @@ export declare class OfficeSDK extends TinyEmitter {
|
|
|
110
156
|
* 比如受浏览器限制无法发出 postMessage() 时,Promise 将会一直 pending。
|
|
111
157
|
*/
|
|
112
158
|
init(): Promise<void>;
|
|
113
|
-
private setupLoadingOverlay;
|
|
114
|
-
private removeLoadingOverlay;
|
|
115
|
-
private ensureLoadingStyle;
|
|
116
159
|
private initIframe;
|
|
160
|
+
private runPreloadHandshake;
|
|
117
161
|
private initChannel;
|
|
118
162
|
/**
|
|
119
163
|
* 初始化处理编辑器需要容器返回数据的方法
|
|
120
164
|
*/
|
|
121
165
|
private bindContainerMethodHandlers;
|
|
166
|
+
private initHeaderBarsFacade;
|
|
167
|
+
private invokeHeaderBars;
|
|
168
|
+
private syncHeaderBarsCommands;
|
|
169
|
+
private applyHeaderBarsChanged;
|
|
170
|
+
private syncHeaderBarsVisible;
|
|
171
|
+
private setHeaderBarsVisible;
|
|
172
|
+
private getHeaderBarsCommandRef;
|
|
122
173
|
private initEditor;
|
|
123
174
|
private shouldHandleMessage;
|
|
124
175
|
private getContainerRect;
|
|
@@ -188,11 +239,25 @@ export declare enum Event {
|
|
|
188
239
|
* OfficeSDK 状态变化事件
|
|
189
240
|
*/
|
|
190
241
|
ReadyState = "readyState",
|
|
242
|
+
/**
|
|
243
|
+
* 编辑器真正完成"首屏渲染"的信号。
|
|
244
|
+
*
|
|
245
|
+
* 由 iframe 内编辑器在自身渲染稳定后通过 channel 发送,SDK 侧转发为本事件。
|
|
246
|
+
* 宿主可按需监听它来区分 SDK Ready 与编辑器视觉首屏完成。
|
|
247
|
+
*/
|
|
248
|
+
EditorRendered = "editorRendered",
|
|
191
249
|
/**
|
|
192
250
|
* 编辑器事件
|
|
193
251
|
*/
|
|
194
252
|
EditorEvent = "editorEvent"
|
|
195
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* iframe 内侧用来上报"编辑器已完成首屏渲染"的 channel 事件名。
|
|
256
|
+
*
|
|
257
|
+
* 与 `InvokeMethod.ReadyState` 的枚举值保持在同一命名空间,但不入 shared 包,
|
|
258
|
+
* 以免跨端版本耦合。iframe 侧约定写字符串即可。
|
|
259
|
+
*/
|
|
260
|
+
export declare const EDITOR_RENDERED_EVENT = "editorRendered";
|
|
196
261
|
export interface Message {
|
|
197
262
|
uuid?: string;
|
|
198
263
|
event: string;
|
|
@@ -222,6 +287,20 @@ export type EventCallback = (...args: any[]) => any;
|
|
|
222
287
|
export interface SDKToastOptions {
|
|
223
288
|
[key: string]: string | SDKToastOptions | undefined;
|
|
224
289
|
}
|
|
290
|
+
/**
|
|
291
|
+
* iframe 内置加载页配置,只支持可序列化字段。
|
|
292
|
+
*/
|
|
293
|
+
export interface LoadingOptions {
|
|
294
|
+
/**
|
|
295
|
+
* 自定义加载页 Logo。传字符串时作为图片 URL / dataURL 使用;
|
|
296
|
+
* 传 false 时隐藏 Logo;不传时使用 iframe 内默认石墨 Logo。
|
|
297
|
+
*/
|
|
298
|
+
logo?: string | false;
|
|
299
|
+
/**
|
|
300
|
+
* 自定义加载页提示文案。不传时使用 iframe 内默认文案。
|
|
301
|
+
*/
|
|
302
|
+
tip?: string;
|
|
303
|
+
}
|
|
225
304
|
/**
|
|
226
305
|
* OfficeSDK 初始化参数
|
|
227
306
|
*/
|
|
@@ -256,6 +335,10 @@ export interface OfficeSDKOptions extends Omit<ContainerMethods, 'getContainerRe
|
|
|
256
335
|
params?: {
|
|
257
336
|
[key: string]: string;
|
|
258
337
|
};
|
|
338
|
+
/**
|
|
339
|
+
* 当前打开模式。`preview` 用于预览态,其余场景默认按 `edit` 处理。
|
|
340
|
+
*/
|
|
341
|
+
mode?: 'edit' | 'preview';
|
|
259
342
|
/**
|
|
260
343
|
* 石墨 SDK URL 参数 url?smParams={params},用于传递石墨 SDK 内部需要的参数。
|
|
261
344
|
*/
|
|
@@ -311,14 +394,24 @@ export interface OfficeSDKOptions extends Omit<ContainerMethods, 'getContainerRe
|
|
|
311
394
|
* 是否禁用默认的签名组件,以支持自定义签名组件。受版本限制,部分版本的特定类型文档才支持。
|
|
312
395
|
*/
|
|
313
396
|
disableSignatureComponent?: boolean;
|
|
397
|
+
/**
|
|
398
|
+
* 控制 headerbar 组件是否展示,false 表示隐藏。
|
|
399
|
+
*/
|
|
400
|
+
headerBarsVisible?: boolean;
|
|
314
401
|
/**
|
|
315
402
|
* 是否显示内置的加载动画,只在静态资源加载到编辑器渲染这个阶段显示
|
|
316
403
|
*/
|
|
317
404
|
showLoadingEffect?: boolean;
|
|
318
405
|
/**
|
|
319
|
-
*
|
|
406
|
+
* 是否启用 iframe 内置默认加载页,默认 false。
|
|
407
|
+
* 隐藏后接入方可自定义外部 loading。
|
|
320
408
|
*/
|
|
321
409
|
showLoading?: boolean;
|
|
410
|
+
/**
|
|
411
|
+
* iframe 内置加载页配置。仅在 `showLoading === true`
|
|
412
|
+
* 或 `showLoadingEffect === true` 时透传给 iframe。
|
|
413
|
+
*/
|
|
414
|
+
loadingOptions?: LoadingOptions;
|
|
322
415
|
/**
|
|
323
416
|
* 用于在编辑器发起 API 请求时,对请求参数进行修改的函数。详细用法见文档。
|
|
324
417
|
*/
|
|
@@ -335,4 +428,17 @@ export interface OfficeSDKOptions extends Omit<ContainerMethods, 'getContainerRe
|
|
|
335
428
|
* 加密后的用户id
|
|
336
429
|
*/
|
|
337
430
|
userUuid?: string;
|
|
431
|
+
/**
|
|
432
|
+
* 缺省页(Empty Page)配置。
|
|
433
|
+
* - 不传或传 `true`:启用默认缺省页能力(有内置图片与默认文案,**无按钮**)
|
|
434
|
+
* - 传 `false`:完全关闭
|
|
435
|
+
* - 传对象:精细控制启用的 scene、token 过期策略,以及每个 scene 的
|
|
436
|
+
* 文案/按钮自定义(`overrides`)。默认不渲染任何按钮,宿主需要按钮时必须
|
|
437
|
+
* 在 `overrides[scene].primary/secondary` 里显式配置 label,点击统一触发
|
|
438
|
+
* `emptyPageAction` 事件由宿主处理。
|
|
439
|
+
*
|
|
440
|
+
* 相关事件:`emptyPageShown` / `emptyPageAction` / `emptyPageHidden`。
|
|
441
|
+
* 详见 `./types/EmptyPage.ts`。
|
|
442
|
+
*/
|
|
443
|
+
emptyPage?: boolean | EmptyPageOptions;
|
|
338
444
|
}
|
|
@@ -9,5 +9,7 @@ import { EventMap as BaseEventMap, BaseEditor } from './types/BaseEditor';
|
|
|
9
9
|
export * from 'weboffice-js-sdk-shared';
|
|
10
10
|
export * from './connect';
|
|
11
11
|
export * from './OfficeSDK';
|
|
12
|
+
export type { EmptyPageScene, EmptyPageOptions, EmptyPageActionOverride, EmptyPageContentOverride, NormalizedEmptyPageOptions, EmptyPageShownPayload, EmptyPageActionPayload, EmptyPageHiddenPayload, FileOpenFailedReason, TokenExpiredStrategy } from './types/EmptyPage';
|
|
13
|
+
export { ALL_EMPTY_PAGE_SCENES, normalizeEmptyPageOptions } from './types/EmptyPage';
|
|
12
14
|
export { BaseEditor, DocumentPro, Document, Spreadsheet, Presentation, Table, Form, Flowchart, BaseEventMap };
|
|
13
15
|
export declare const START_PARAMS_FIELD = "smParams";
|