提交 fe0aed6f 编写于 作者: D DCloud_LXH

chore: useSubscribe use registerViewMethod、unregisterViewMethod

上级 e04824a1
......@@ -43,31 +43,27 @@ import { TEMP_PATH } from '@dcloudio/uni-platform'
//#region UniServiceJSBridge
const canvasEventCallbacks = createCallbacks('canvasEvent')
const onCanvasMethodCallback = /*#__PURE__*/ once(() => {
UniServiceJSBridge.subscribe(
'onCanvasMethodCallback',
({ callbackId, data }: { callbackId: number | string; data: any }) => {
const callback = canvasEventCallbacks.pop(callbackId)
if (callback) {
callback(data)
}
}
)
})
function operateCanvas(
canvasId: string,
pageId: number,
type: unknown,
data: any
) {
UniServiceJSBridge.publishHandler(
'canvas.' + canvasId,
UniServiceJSBridge.invokeViewMethod<
{},
{ callbackId: number | string; data: any }
>(
`canvas.${canvasId}`,
{
canvasId,
type,
data,
},
({ callbackId, data }) => {
const callback = canvasEventCallbacks.pop(callbackId)
if (callback) {
callback(data)
}
},
pageId
)
}
......@@ -1046,7 +1042,7 @@ export const canvasGetImageData =
defineAsyncApi<API_TYPE_CANVAS_GET_IMAGE_DATA>(
API_CANVAS_GET_IMAGE_DATA,
({ canvasId, x, y, width, height }, { resolve, reject }) => {
onCanvasMethodCallback()
// onCanvasMethodCallback()
const pageId = getPageIdByVm(getCurrentPageVm()!)!
if (!pageId) {
reject()
......@@ -1085,7 +1081,7 @@ export const canvasPutImageData =
defineAsyncApi<API_TYPE_CANVAS_PUT_IMAGE_DATA>(
API_CANVAS_PUT_IMAGE_DATA,
({ canvasId, data, x, y, width, height }, { resolve, reject }) => {
onCanvasMethodCallback()
// onCanvasMethodCallback()
var pageId = getPageIdByVm(getCurrentPageVm()!)!
if (!pageId) {
reject()
......@@ -1144,7 +1140,7 @@ export const canvasToTempFilePath =
},
{ resolve, reject }
) => {
onCanvasMethodCallback()
// onCanvasMethodCallback()
var pageId = getPageIdByVm(getCurrentPageVm()!)!
if (!pageId) {
reject()
......
......@@ -8,7 +8,7 @@ import {
withWebEvent,
defineBuiltInComponent,
} from '@dcloudio/uni-components'
import { getCurrentPageId, onEventPrevent } from '@dcloudio/uni-core'
import { onEventPrevent } from '@dcloudio/uni-core'
import {
saveImage,
getSameOriginUrl,
......@@ -67,6 +67,11 @@ const props = {
}
type Props = ExtractPropTypes<typeof props>
type triggerMethodsName =
| 'actionsChanged'
| 'getImageData'
| 'putImageData'
| 'toTempFilePath'
export default /*#__PURE__*/ defineBuiltInComponent({
inheritAttrs: false,
......@@ -94,11 +99,20 @@ export default /*#__PURE__*/ defineBuiltInComponent({
const { _handleSubscribe, _resize } = useMethods(canvas, actionsWaiting)
useSubscribe(
_handleSubscribe as (type: string, data: unknown) => void,
_handleSubscribe as (
type: string,
data: unknown,
resolve: (res: any) => void
) => void,
useContextInfo(props.canvasId),
true
)
/* registerViewMethod<
{ type: triggerMethodsName; data: any },
{ callbackId: number; data: any }
>(getCurrentPageId(), `canvas.${props.canvasId}`, _handleSubscribe) */
onMounted(() => {
_resize()
})
......@@ -214,15 +228,18 @@ function useMethods(
wrapper(canvas)
}
}
function actionsChanged({
actions,
reserve,
callbackId,
}: {
actions: Actions
reserve: boolean
callbackId: number
}) {
function actionsChanged(
{
actions,
reserve,
callbackId,
}: {
actions: Actions
reserve: boolean
callbackId: number
},
resolve: (res: { callbackId: number; data: any }) => void
) {
if (!actions) {
return
}
......@@ -284,6 +301,7 @@ function useMethods(
data[1] as string,
actions.slice(index + 1),
callbackId,
resolve,
function (image) {
if (image) {
c2d[method1] = c2d.createPattern(image, data[2] as string)!
......@@ -357,6 +375,7 @@ function useMethods(
url,
actions.slice(index + 1),
callbackId,
resolve,
function (image) {
if (image) {
c2d.drawImage.apply(
......@@ -391,16 +410,12 @@ function useMethods(
}
}
if (!actionsWaiting.value && callbackId) {
UniViewJSBridge.publishHandler(
'onCanvasMethodCallback',
{
callbackId,
data: {
errMsg: 'drawCanvas:ok',
},
resolve({
callbackId,
data: {
errMsg: 'drawCanvas:ok',
},
getCurrentPageId()
)
})
}
}
function preloadImage(actions: Actions) {
......@@ -453,6 +468,7 @@ function useMethods(
src: string,
actions: Actions,
callbackId: number,
resolve: (res: { callbackId: number; data: any }) => void,
fn: (a: CanvasImageSource) => void
) {
var image = _images[src]
......@@ -469,42 +485,48 @@ function useMethods(
var actions = _actionsDefer.slice(0)
_actionsDefer = []
for (var action = actions.shift(); action; ) {
actionsChanged({
actions: action[0],
reserve: action[1],
callbackId,
})
actionsChanged(
{
callbackId,
actions: action[0],
reserve: action[1],
},
resolve
)
action = actions.shift()
}
}
return false
}
}
function getImageData({
x = 0,
y = 0,
width,
height,
destWidth,
destHeight,
hidpi = true,
dataType,
quality = 1,
type = 'png',
callbackId,
}: {
x: number
y: number
width: number
height: number
destWidth: number
destHeight: number
hidpi: boolean
dataType: string
quality: number
type: string
callbackId?: number
}) {
function getImageData(
{
x = 0,
y = 0,
width,
height,
destWidth,
destHeight,
hidpi = true,
dataType,
quality = 1,
type = 'png',
callbackId,
}: {
x: number
y: number
width: number
height: number
destWidth: number
destHeight: number
hidpi: boolean
dataType: string
quality: number
type: string
callbackId?: number
},
resolve?: (res: { callbackId: number; data: any }) => void
) {
const canvas = canvasRef.value!
let data: string | number[]
const maxWidth = canvas.offsetWidth - x
......@@ -580,33 +602,33 @@ function useMethods(
if (!callbackId) {
return result
} else {
UniViewJSBridge.publishHandler(
'onCanvasMethodCallback',
{
resolve &&
resolve({
callbackId,
data: result,
},
getCurrentPageId()
)
})
}
}
function putImageData({
data,
x,
y,
width,
height,
compressed,
callbackId,
}: {
data: Array<number>
x: number
y: number
width: number
height: number
compressed: boolean
callbackId: number
}) {
function putImageData(
{
data,
x,
y,
width,
height,
compressed,
callbackId,
}: {
data: Array<number>
x: number
y: number
width: number
height: number
compressed: boolean
callbackId: number
},
resolve: (res: { callbackId: number; data: any }) => void
) {
try {
if (!height) {
height = Math.round(data.length / 4 / width)
......@@ -625,52 +647,47 @@ function useMethods(
canvasRef.value!.getContext('2d')!.drawImage(canvas, x, y, width, height)
canvas.height = canvas.width = 0
} catch (error) {
UniViewJSBridge.publishHandler(
'onCanvasMethodCallback',
{
callbackId,
data: {
errMsg: 'canvasPutImageData:fail',
},
},
getCurrentPageId()
)
return
}
UniViewJSBridge.publishHandler(
'onCanvasMethodCallback',
{
resolve({
callbackId,
data: {
errMsg: 'canvasPutImageData:ok',
errMsg: 'canvasPutImageData:fail',
},
})
return
}
resolve({
callbackId,
data: {
errMsg: 'canvasPutImageData:ok',
},
getCurrentPageId()
)
})
}
function toTempFilePath({
x = 0,
y = 0,
width,
height,
destWidth,
destHeight,
fileType,
quality,
dirname,
callbackId,
}: {
x: number
y: number
width: number
height: number
destWidth: number
destHeight: number
fileType: string
quality: number
dirname: string
callbackId: number
}) {
function toTempFilePath(
{
x = 0,
y = 0,
width,
height,
destWidth,
destHeight,
fileType,
quality,
dirname,
callbackId,
}: {
x: number
y: number
width: number
height: number
destWidth: number
destHeight: number
fileType: string
quality: number
dirname: string
callbackId: number
},
resolve: (res: { callbackId: number; data: any }) => void
) {
const res = getImageData({
x,
y,
......@@ -684,16 +701,12 @@ function useMethods(
quality,
})!
if (!res.data || !res.data.length) {
UniViewJSBridge.publishHandler(
'onCanvasMethodCallback',
{
callbackId,
data: {
errMsg: res!.errMsg.replace('canvasPutImageData', 'toTempFilePath'),
},
resolve({
callbackId,
data: {
errMsg: res!.errMsg.replace('canvasPutImageData', 'toTempFilePath'),
},
getCurrentPageId()
)
})
return
}
saveImage(res.data as string, dirname, (error, tempFilePath) => {
......@@ -701,17 +714,13 @@ function useMethods(
if (error) {
errMsg += ` ${error.message}`
}
UniViewJSBridge.publishHandler(
'onCanvasMethodCallback',
{
callbackId,
data: {
errMsg,
tempFilePath: tempFilePath,
},
resolve({
callbackId,
data: {
errMsg,
tempFilePath: tempFilePath,
},
getCurrentPageId()
)
})
})
}
......@@ -722,10 +731,14 @@ function useMethods(
toTempFilePath,
}
function _handleSubscribe(type: keyof typeof methods, data = {}) {
function _handleSubscribe(
type: triggerMethodsName,
data: any,
resolve: (res: { callbackId: number; data: any }) => void
) {
let method = methods[type]
if (type.indexOf('_') !== 0 && typeof method === 'function') {
method(data as any)
method(data as any, resolve)
}
}
......
......@@ -6,9 +6,8 @@ import QuillClass, {
RangeStatic,
StringMap,
} from 'quill'
import { useContextInfo } from '@dcloudio/uni-components'
import { useContextInfo, useSubscribe } from '@dcloudio/uni-components'
import { getRealPath } from '@dcloudio/uni-platform'
import { getCurrentPageId, registerViewMethod } from '@dcloudio/uni-core'
import { CustomEventTrigger } from '../../../helpers/useEvent'
import HTMLParser from '../../../helpers/html-parser'
import loadScript from './loadScript'
......@@ -56,7 +55,6 @@ interface WindowExt extends Window {
export function useQuill(
props: {
id: string
readOnly?: any
placeholder?: any
showImgSize?: any
......@@ -257,169 +255,168 @@ export function useQuill(
}
})
})
registerViewMethod<
{
type: string
data: { callbackId?: string; options: any }
},
{ callbackId: string; data: any }
>(getCurrentPageId(), `editor.${props.id}`, ({ type, data }, resolve) => {
const { options, callbackId } = data
let res
let range: RangeStatic | undefined
let errMsg
if (quillReady) {
const Quill = (window as WindowExt).Quill as typeof QuillClass
switch (type) {
case 'format':
{
let { name = '', value = false } = options
range = quill.getSelection(true)
let format = quill.getFormat(range)[name] || false
if (
['bold', 'italic', 'underline', 'strike', 'ins'].includes(name)
) {
value = !format
} else if (name === 'direction') {
value = value === 'rtl' && format ? false : value
const align = quill.getFormat(range).align
if (value === 'rtl' && !align) {
quill.format('align', 'right', 'user')
} else if (!value && align === 'right') {
quill.format('align', false, 'user')
}
} else if (name === 'indent') {
const rtl = quill.getFormat(range).direction === 'rtl'
value = value === '+1'
if (rtl) {
value = !value
}
value = value ? '+1' : '-1'
} else {
if (name === 'list') {
value = value === 'check' ? 'unchecked' : value
format = format === 'checked' ? 'unchecked' : format
const id = useContextInfo()
useSubscribe<{ callbackId: string; data: any }>(
(type, data: any, resolve) => {
const { options, callbackId } = data
let res
let range: RangeStatic | undefined
let errMsg
if (quillReady) {
const Quill = (window as WindowExt).Quill as typeof QuillClass
switch (type) {
case 'format':
{
let { name = '', value = false } = options
range = quill.getSelection(true)
let format = quill.getFormat(range)[name] || false
if (
['bold', 'italic', 'underline', 'strike', 'ins'].includes(name)
) {
value = !format
} else if (name === 'direction') {
value = value === 'rtl' && format ? false : value
const align = quill.getFormat(range).align
if (value === 'rtl' && !align) {
quill.format('align', 'right', 'user')
} else if (!value && align === 'right') {
quill.format('align', false, 'user')
}
} else if (name === 'indent') {
const rtl = quill.getFormat(range).direction === 'rtl'
value = value === '+1'
if (rtl) {
value = !value
}
value = value ? '+1' : '-1'
} else {
if (name === 'list') {
value = value === 'check' ? 'unchecked' : value
format = format === 'checked' ? 'unchecked' : format
}
value =
(format && format !== (value || false)) || (!format && value)
? value
: !format
}
value =
(format && format !== (value || false)) || (!format && value)
? value
: !format
quill.format(name, value, 'user')
}
quill.format(name, value, 'user')
}
break
case 'insertDivider':
range = quill.getSelection(true)
quill.insertText(range.index, '\n', 'user')
quill.insertEmbed(range.index + 1, 'divider', true, 'user')
quill.setSelection(range.index + 2, 0, 'silent')
break
case 'insertImage':
{
range = quill.getSelection(true)
const {
src = '',
alt = '',
width = '',
height = '',
extClass = '',
data = {},
} = options
const path = getRealPath(src)
quill.insertEmbed(range.index, 'image', path, 'user')
const local = /^(file|blob):/.test(path) ? path : false
textChanging = true
quill.formatText(range.index, 1, 'data-local', local)
quill.formatText(range.index, 1, 'alt', alt)
quill.formatText(range.index, 1, 'width', width)
quill.formatText(range.index, 1, 'height', height)
quill.formatText(range.index, 1, 'class', extClass)
textChanging = false
quill.formatText(
range.index,
1,
'data-custom',
Object.keys(data)
.map((key) => `${key}=${data[key]}`)
.join('&')
)
quill.setSelection(range.index + 1, 0, 'silent')
}
break
case 'insertText':
{
break
case 'insertDivider':
range = quill.getSelection(true)
const { text = '' } = options
quill.insertText(range.index, text, 'user')
quill.setSelection(range.index + text.length, 0, 'silent')
}
break
case 'setContents':
{
const { delta, html } = options
if (typeof delta === 'object') {
quill.setContents(delta, 'silent')
} else if (typeof html === 'string') {
quill.setContents(html2delta(html), 'silent')
} else {
errMsg = 'contents is missing'
quill.insertText(range.index, '\n', 'user')
quill.insertEmbed(range.index + 1, 'divider', true, 'user')
quill.setSelection(range.index + 2, 0, 'silent')
break
case 'insertImage':
{
range = quill.getSelection(true)
const {
src = '',
alt = '',
width = '',
height = '',
extClass = '',
data = {},
} = options
const path = getRealPath(src)
quill.insertEmbed(range.index, 'image', path, 'user')
const local = /^(file|blob):/.test(path) ? path : false
textChanging = true
quill.formatText(range.index, 1, 'data-local', local)
quill.formatText(range.index, 1, 'alt', alt)
quill.formatText(range.index, 1, 'width', width)
quill.formatText(range.index, 1, 'height', height)
quill.formatText(range.index, 1, 'class', extClass)
textChanging = false
quill.formatText(
range.index,
1,
'data-custom',
Object.keys(data)
.map((key) => `${key}=${data[key]}`)
.join('&')
)
quill.setSelection(range.index + 1, 0, 'silent')
}
}
break
case 'getContents':
res = getContents()
break
case 'clear':
quill.setText('')
break
case 'removeFormat':
{
range = quill.getSelection(true)
const parchment = Quill.import('parchment')
if (range.length) {
quill.removeFormat(range.index, range.length, 'user')
} else {
Object.keys(quill.getFormat(range)).forEach((key) => {
if (parchment.query(key, parchment.Scope.INLINE)) {
quill.format(key, false)
}
})
break
case 'insertText':
{
range = quill.getSelection(true)
const { text = '' } = options
quill.insertText(range.index, text, 'user')
quill.setSelection(range.index + text.length, 0, 'silent')
}
}
break
case 'undo':
quill.history.undo()
break
case 'redo':
quill.history.redo()
break
case 'blur':
quill.blur()
break
case 'getSelectionText':
range = quill.selection.savedRange
res = { text: '' }
if (range && range.length !== 0) {
res.text = quill.getText(range.index, range.length)
}
break
case 'scrollIntoView':
quill.scrollIntoView()
break
default:
break
break
case 'setContents':
{
const { delta, html } = options
if (typeof delta === 'object') {
quill.setContents(delta, 'silent')
} else if (typeof html === 'string') {
quill.setContents(html2delta(html), 'silent')
} else {
errMsg = 'contents is missing'
}
}
break
case 'getContents':
res = getContents()
break
case 'clear':
quill.setText('')
break
case 'removeFormat':
{
range = quill.getSelection(true)
const parchment = Quill.import('parchment')
if (range.length) {
quill.removeFormat(range.index, range.length, 'user')
} else {
Object.keys(quill.getFormat(range)).forEach((key) => {
if (parchment.query(key, parchment.Scope.INLINE)) {
quill.format(key, false)
}
})
}
}
break
case 'undo':
quill.history.undo()
break
case 'redo':
quill.history.redo()
break
case 'blur':
quill.blur()
break
case 'getSelectionText':
range = quill.selection.savedRange
res = { text: '' }
if (range && range.length !== 0) {
res.text = quill.getText(range.index, range.length)
}
break
case 'scrollIntoView':
quill.scrollIntoView()
break
default:
break
}
updateStatus(range)
} else {
errMsg = 'not ready'
}
updateStatus(range)
} else {
errMsg = 'not ready'
}
if (callbackId) {
resolve({
callbackId,
data: extend({}, res, {
errMsg: `${type}:${errMsg ? 'fail ' + errMsg : 'ok'}`,
}),
})
}
})
if (callbackId) {
resolve({
callbackId,
data: extend({}, res, {
errMsg: `${type}:${errMsg ? 'fail ' + errMsg : 'ok'}`,
}),
})
}
},
id,
true
)
}
......@@ -27,7 +27,7 @@ export function useContextInfo(_id?: string) {
page,
}
})
return `${page}.${type}.${id}`
return `${type}.${id}`
}
export function getContextInfo(el: HTMLElement | HTMLElementWithContextInfo) {
return (el as HTMLElementWithContextInfo).__uniContextInfo
......
......@@ -5,30 +5,41 @@ import {
getCurrentInstance,
ComponentPublicInstance,
} from 'vue'
import { useCurrentPageId } from '@dcloudio/uni-core'
import {
getCurrentPageId,
registerViewMethod,
unregisterViewMethod,
} from '@dcloudio/uni-core'
function normalizeEvent(
pageId: number,
vm: ComponentPublicInstance,
id?: string
) {
type SubscribeCallbackRes<Res = any> = (
type: string,
data: unknown,
resolve: (res: Res) => void
) => void
function normalizeEvent(vm: ComponentPublicInstance, id?: string) {
if (!id) {
id = (vm as any).id
}
if (!id) {
return
}
return pageId + '.' + vm.$options.name!.toLowerCase() + '.' + id
return vm.$options.name!.toLowerCase() + '.' + id
}
function addSubscribe(name: string, callback: Function) {
function addSubscribe(name: string, callback: SubscribeCallbackRes) {
if (!name) {
return
}
UniViewJSBridge.subscribe(
registerViewMethod(
getCurrentPageId(),
name,
({ type, data }: { type: string; data: unknown }) => {
callback(type, data)
(
{ type, data }: { type: string; data: unknown },
resolve: Parameters<SubscribeCallbackRes>[2]
) => {
callback(type, data, resolve)
}
)
}
......@@ -37,31 +48,30 @@ function removeSubscribe(name: string) {
if (!name) {
return
}
UniViewJSBridge.unsubscribe(name)
unregisterViewMethod(getCurrentPageId(), name)
}
export function useSubscribe(
callback: (type: string, data: unknown) => void,
export function useSubscribe<Res = any>(
callback: SubscribeCallbackRes<Res>,
name?: string,
multiple?: boolean
) {
const instance = getCurrentInstance()!
const vm = instance.proxy!
const pageId = multiple || !name ? useCurrentPageId() : 0
onMounted(() => {
addSubscribe(name || normalizeEvent(pageId, vm)!, callback)
addSubscribe(name || normalizeEvent(vm)!, callback)
if (multiple || !name) {
watch(
() => (vm as any).id,
(value, oldValue) => {
addSubscribe(normalizeEvent(pageId, vm, value)!, callback)
removeSubscribe(oldValue && normalizeEvent(pageId, vm, oldValue)!)
addSubscribe(normalizeEvent(vm, value)!, callback)
removeSubscribe(oldValue && normalizeEvent(vm, oldValue)!)
}
)
}
})
onBeforeUnmount(() => {
removeSubscribe(name || normalizeEvent(pageId, vm)!)
removeSubscribe(name || normalizeEvent(vm)!)
})
}
......
......@@ -50,6 +50,11 @@ export function registerViewMethod<Args = any, Res = any>(
}
}
export function unregisterViewMethod(pageId: number, name: string) {
name = normalizeViewMethodName(pageId, name)
delete viewMethods[name]
}
function onInvokeViewMethod(
{
id,
......
......@@ -3,6 +3,7 @@ export {
subscribeViewMethod,
unsubscribeViewMethod,
registerViewMethod,
unregisterViewMethod,
} from './bridge'
export { initView } from './init'
export { initViewPlugin } from './plugin'
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册