diff --git a/README.md b/README.md index 36607185..c805c2fe 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,8 @@ showToast({ type: 'success', duration: 1000, success: () => { - console.log('toast') - } + console.log('toast'); + }, }); // promise @@ -60,9 +60,9 @@ showToast({ ## 示例 -|微信小程序|支付宝小程序| -|--------|----------| -||| +| 微信小程序 | 支付宝小程序 | +| ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| | | ## 贡献代码 @@ -89,7 +89,7 @@ $ yarn demo:dev ### 更新版本 -API package 版本统一维护在根目录下的api-config.js,以 @uni/toast 为例: +API package 版本统一维护在根目录下的 api-config.js,以 @uni/toast 为例: ```js module.exports = { @@ -102,15 +102,16 @@ module.exports = { }, ], }, -} +}; ``` -| 参数 | 含义 | 默认值 | -|----|----|----| -|path| 在源文件的路径| -| -|pkgInfo| npm包的属性(同packagejson写法)| -| -|needCommonUtil| 是否需要公共utils| true| -|unNeedSplit| 是否需要安环境分包| false| +| 参数 | 含义 | 默认值 | +| -------------- | ----------------------------------- | ------ | +| path | 在源文件的路径 | - | +| pkgInfo | npm 包的属性(同 packagejson 写法) | - | +| needCommonUtil | 是否需要公共 utils | true | +| unNeedSplit | 是否需要安环境分包 | false | +| exportMain | 是否需要导出到大包中 | true | 大包版本需要更新根目录下的 package.json 的 version diff --git a/api-config.js b/api-config.js index 09d636d2..edb1ae63 100644 --- a/api-config.js +++ b/api-config.js @@ -381,4 +381,17 @@ module.exports = { }, ], }, + utils: { + path: 'src/packages/utils/src/index.ts', + unNeedSplit: true, + needCommonUtil: false, + exportMain: false, + pkgInfo: [ + { + version: '1.0.0', + name: '@uni/utils', + exports: '', + }, + ], + }, }; diff --git a/migrate.js b/migrate.js new file mode 100644 index 00000000..fac6698d --- /dev/null +++ b/migrate.js @@ -0,0 +1,69 @@ +const glob = require('glob'); +const fs = require('fs-extra'); +const babelParser = require('@babel/parser'); +const traverse = require('@babel/traverse').default; +const types = require('@babel/types'); +const generate = require('@babel/generator').default; + + +function parse(file) { + const source = fs.readFileSync(file, { encoding: 'utf8' }); + let ast; + try { + ast = babelParser.parse(source, { + sourceType: 'module', + plugins: [ + 'typescript', + 'classProperties', + 'objectRestSpread', + 'optionalCatchBinding', + 'dynamicImport', + 'decorators-legacy', + 'asyncGenerators', + 'exportDefaultFrom', + 'exportNamespaceFrom', + 'optionalCatchBinding', + 'throwExpressions', + 'optionalChaining', + 'nullishCoalescingOperator', + ], + }); + } catch (e) { + console.error('error', file); + return; + } + + if (!ast) { + console.error('error', file); + return; + } + let changed = false; + traverse(ast, { + Program(path) { + const { body } = path.node; + let specifiers = []; + const indexs = []; + body.forEach((n, index) => { + if (types.isImportDeclaration(n) && n.source.value.startsWith('@utils')) { + specifiers = specifiers.concat(n.specifiers); + indexs.push(index); + } + }); + + if (indexs.length > 0) { + indexs.reverse().forEach(i => body.splice(i, 1)); + changed = true; + body.unshift(types.importDeclaration(specifiers, types.stringLiteral('@uni/utils'))); + } + }, + }); + if (changed) { + fs.writeFileSync(file, generate(ast, {}, source).code); + } +} + +glob('./src/packages/**/src/**/*.ts', function(err, files) { + files.forEach(file => { + parse(file); + }); +}); \ No newline at end of file diff --git a/package.json b/package.json index ce535996..a69bf135 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "@uni/apis", "private": true, "version": "1.1.10", + "sideEffects": false, "scripts": { "setup": "rm -rf node_modules && yarn install --no-lockfile", "lint": "eslint --ext .js --ext .jsx --ext .ts --ext .tsx ./src/packages/**/src --fix", diff --git a/scripts/build-plugin/buildMain.js b/scripts/build-plugin/buildMain.js index 96125fb6..7256cdf2 100644 --- a/scripts/build-plugin/buildMain.js +++ b/scripts/build-plugin/buildMain.js @@ -4,7 +4,13 @@ const path = require('path'); const needRename = { location: '_location' } -module.exports = (rootDir, sourceMap) => { +module.exports = (rootDir, originSourceMap) => { + const sourceMap = Object.keys(originSourceMap).reduce((prev, cur) => { + if (originSourceMap[cur].exportMain !== false) { + prev[cur] = originSourceMap[cur]; + } + return prev; + }, {}); const defaultContent = '\r\n\r\nexport default {\r\n' + Object.entries(sourceMap).map(([key, value]) => { if (needRename[key]) { return ` ${key}: ${needRename[key]},`; diff --git a/scripts/build-plugin/gulp/conf/babel.js b/scripts/build-plugin/gulp/conf/babel.js index 8ea37f66..eaa24db7 100644 --- a/scripts/build-plugin/gulp/conf/babel.js +++ b/scripts/build-plugin/gulp/conf/babel.js @@ -33,26 +33,26 @@ module.exports = (isEs, isMain, aliasEntries) => { * resolvePath: ..., * } */ - const oriUtilsPath = '@utils'; - let newUtilsPath = '_utils'; - let pathLv = 0; - if (sourcePath.indexOf(oriUtilsPath) !== -1) { - if (isMain) { - newUtilsPath = 'utils' - pathLv = currentFile - .match(/(src\/packages\/.*\.ts)/)[1] - .split('/').length - 2; - } else { - pathLv = currentFile - .replace('/src/packages', '') - .match(/(src\/.*\.ts)/)[1] - .split('/').length - 2; - } + // const oriUtilsPath = '@utils'; + // let newUtilsPath = '_utils'; + // let pathLv = 0; + // if (sourcePath.indexOf(oriUtilsPath) !== -1) { + // if (isMain) { + // newUtilsPath = 'utils' + // pathLv = currentFile + // .match(/(src\/packages\/.*\.ts)/)[1] + // .split('/').length - 2; + // } else { + // pathLv = currentFile + // .replace('/src/packages', '') + // .match(/(src\/.*\.ts)/)[1] + // .split('/').length - 2; + // } - const pointRelative = pathLv === 0 ? '.' : Array.from({length: pathLv}).map(i => '..').join('/'); + // const pointRelative = pathLv === 0 ? '.' : Array.from({length: pathLv}).map(i => '..').join('/'); - return sourcePath.replace(oriUtilsPath, pointRelative + '/' + newUtilsPath); - } + // return sourcePath.replace(oriUtilsPath, pointRelative + '/' + newUtilsPath); + // } // 替换内部依赖,加入index.js diff --git a/scripts/build-plugin/gulp/gulpfile.js b/scripts/build-plugin/gulp/gulpfile.js index 16039601..8cc24326 100644 --- a/scripts/build-plugin/gulp/gulpfile.js +++ b/scripts/build-plugin/gulp/gulpfile.js @@ -52,7 +52,7 @@ const tsProject = ts.createProject({ // "@types/*": ["types/*"], // "types/interface": ["./interface"], "@/*": ["src/*"], - "@utils/*": ["src/utils/*"], + // "@utils/*": ["src/utils/*"], } }); diff --git a/scripts/build-plugin/initPkg.js b/scripts/build-plugin/initPkg.js index d9176ad1..8d3ba502 100644 --- a/scripts/build-plugin/initPkg.js +++ b/scripts/build-plugin/initPkg.js @@ -33,6 +33,10 @@ const buildPkgJson = async (packageInfo, outputPath, isMain = false) => { } if (isMain || packageInfo.name == '@uni/env') { delete packageJson.dependencies['@uni/env']; + delete packageJson.dependencies['@uni/utils']; + } + if (packageInfo.name === '@uni/utils') { + delete packageJson.dependencies['@uni/utils']; } if (isMain) { packageJson.typings = 'types/main/index.d.ts'; diff --git a/scripts/build-plugin/source/package-tpl.js b/scripts/build-plugin/source/package-tpl.js index 1c04a0ef..8e0f52c7 100644 --- a/scripts/build-plugin/source/package-tpl.js +++ b/scripts/build-plugin/source/package-tpl.js @@ -21,6 +21,7 @@ module.exports = { }, 'dependencies': { '@uni/env': '^1.0.0', + '@uni/utils': "^1.0.0" }, "repository": { "type": "git", diff --git a/src/packages/canvas/src/ali-miniapp/createContext.ts b/src/packages/canvas/src/ali-miniapp/createContext.ts index e1e9d101..075de9a7 100644 --- a/src/packages/canvas/src/ali-miniapp/createContext.ts +++ b/src/packages/canvas/src/ali-miniapp/createContext.ts @@ -1,55 +1,82 @@ +import { CONTAINER_NAME } from '@uni/utils'; import { CanvasContext, Options } from '../types'; import { normalize } from '../common'; -import { CONTAINER_NAME } from '@utils/constant'; import { isLessThanVersion } from '@utils/tools'; const createContext = normalize((canvasOptions: Options): Promise => { - const { canvasId, type = '2d' } = canvasOptions; + const { + canvasId, + type = '2d', + } = canvasOptions; + if (isLessThanVersion(my.SDKVersion, '2.7.0')) { return new Promise((resolve) => { const canvasContext = my.createCanvasContext(canvasId); const _clearRect = canvasContext.clearRect; + canvasContext.clearRect = (...args) => { _clearRect.apply(canvasContext, args); + canvasContext.draw(true); }; + const _fill = canvasContext.fill; + canvasContext.fill = (...args) => { _fill.apply(canvasContext, args); + canvasContext.draw(true); }; + const _fillRect = canvasContext.fillRect; + canvasContext.fillRect = (...args) => { _fillRect.apply(canvasContext, args); + canvasContext.draw(true); }; + const _fillText = canvasContext.fillText; + canvasContext.fillText = (...args) => { _fillText.apply(canvasContext, args); + canvasContext.draw(true); }; + const _stroke = canvasContext.stroke; + canvasContext.stroke = (...args) => { _stroke.apply(canvasContext, args); + canvasContext.draw(true); }; + const _strokeRect = canvasContext.strokeRect; + canvasContext.strokeRect = (...args) => { _strokeRect.apply(canvasContext, args); + canvasContext.draw(true); }; + const _strokeText = canvasContext.strokeText; + canvasContext.strokeText = (...args) => { _strokeText.apply(canvasContext, args); + canvasContext.draw(true); }; + Object.defineProperty(canvasContext, 'fillStyle', { get() { return canvasContext.setFillStyle; }, + set(value) { canvasContext.setFillStyle(value); }, + }); resolve(canvasContext); }); @@ -57,18 +84,13 @@ const createContext = normalize((canvasOptions: Options): Promise // 仅 2.7.0+ 基础库版本支持 return new Promise((resolve, reject) => { const query = my.createSelectorQuery(); - query - .select(`#${canvasId}`) - .node() - .exec((res) => { - if (!res[0] || !res[0].node) reject(new Error('The canvas node may not exist.')); - const canvasNode: HTMLCanvasElement = res[0].node; - const canvasContext: CanvasContext = canvasNode.getContext(type); - - resolve(canvasContext); - }); + query.select(`#${canvasId}`).node().exec((res) => { + if (!res[0] || !res[0].node) reject(new Error('The canvas node may not exist.')); + const canvasNode: HTMLCanvasElement = res[0].node; + const canvasContext: CanvasContext = canvasNode.getContext(type); + resolve(canvasContext); + }); }); } }, CONTAINER_NAME.ALIPAY); - export default createContext; diff --git a/src/packages/canvas/src/baidu-smartprogram/createContext.ts b/src/packages/canvas/src/baidu-smartprogram/createContext.ts index 5667e247..7ed616c2 100644 --- a/src/packages/canvas/src/baidu-smartprogram/createContext.ts +++ b/src/packages/canvas/src/baidu-smartprogram/createContext.ts @@ -1,129 +1,170 @@ +import { CONTAINER_NAME } from '@uni/utils'; import { CanvasContext, Options } from '../types'; import { normalize } from '../common'; -import { CONTAINER_NAME } from '@utils/constant'; - const createContext = normalize((canvasOptions: Options): Promise => { - const { canvasId } = canvasOptions; + const { + canvasId, + } = canvasOptions; return new Promise((resolve) => { const canvasContext = swan.createCanvasContext(canvasId); const _clearRect = canvasContext.clearRect; + canvasContext.clearRect = (...args) => { _clearRect.apply(canvasContext, args); + canvasContext.draw(true); }; + const _fill = canvasContext.fill; + canvasContext.fill = (...args) => { _fill.apply(canvasContext, args); + canvasContext.draw(true); }; + const _fillRect = canvasContext.fillRect; + canvasContext.fillRect = (...args) => { _fillRect.apply(canvasContext, args); + canvasContext.draw(true); }; + const _fillText = canvasContext.fillText; + canvasContext.fillText = (...args) => { _fillText.apply(canvasContext, args); + canvasContext.draw(true); }; + const _stroke = canvasContext.stroke; + canvasContext.stroke = (...args) => { _stroke.apply(canvasContext, args); + canvasContext.draw(true); }; + const _strokeRect = canvasContext.strokeRect; + canvasContext.strokeRect = (...args) => { _strokeRect.apply(canvasContext, args); + canvasContext.draw(true); }; + const _strokeText = canvasContext.strokeText; + canvasContext.strokeText = (...args) => { _strokeText.apply(canvasContext, args); + canvasContext.draw(true); }; + Object.defineProperty(canvasContext, 'fillStyle', { get() { return canvasContext.setFillStyle; }, + set(value) { canvasContext.setFillStyle(value); }, + }); Object.defineProperty(canvasContext, 'strokeStyle', { get() { return canvasContext.setStrokeStyle; }, + set(value) { canvasContext.setStrokeStyle(value); }, + }); Object.defineProperty(canvasContext, 'fontSize', { get() { return canvasContext.setFontSize; }, + set(value) { canvasContext.setFontSize(value); }, + }); Object.defineProperty(canvasContext, 'globalAlpha', { get() { return canvasContext.setGlobalAlpha; }, + set(value) { canvasContext.setGlobalAlpha(value); }, + }); Object.defineProperty(canvasContext, 'lineWidth', { get() { return canvasContext.setLineWidth; }, + set(value) { canvasContext.setLineWidth(value); }, + }); Object.defineProperty(canvasContext, 'lineCap', { get() { return canvasContext.setLineCap; }, + set(value) { canvasContext.setLineCap(value); }, + }); Object.defineProperty(canvasContext, 'lineJoin', { get() { return canvasContext.setLineJoin; }, + set(value) { canvasContext.setLineJoin(value); }, + }); Object.defineProperty(canvasContext, 'miterLimit', { get() { return canvasContext.setMiterLimit; }, + set(value) { canvasContext.setMiterLimit(value); }, + }); Object.defineProperty(canvasContext, 'textAlign', { get() { return canvasContext.setTextAlign; }, + set(value) { canvasContext.setTextAlign(value); }, + }); Object.defineProperty(canvasContext, 'textBaseLine', { get() { return canvasContext.setTextBaseLine; }, + set(value) { canvasContext.setTextBaseLine(value); }, + }); resolve(canvasContext); }); }, CONTAINER_NAME.BAIDU); - export default createContext; diff --git a/src/packages/canvas/src/bytedance-microapp/createContext.ts b/src/packages/canvas/src/bytedance-microapp/createContext.ts index ac10f5f7..54737326 100644 --- a/src/packages/canvas/src/bytedance-microapp/createContext.ts +++ b/src/packages/canvas/src/bytedance-microapp/createContext.ts @@ -1,138 +1,176 @@ +import { CONTAINER_NAME } from '@uni/utils'; import { CanvasContext, Options } from '../types'; import { normalize } from '../common'; -import { CONTAINER_NAME } from '@utils/constant'; const createContext = normalize((canvasOptions: Options): Promise => { - const { canvasId, type = '2d', options } = canvasOptions; + const { + canvasId, + type = '2d', + options, + } = canvasOptions; return new Promise((resolve, reject) => { const query = tt.createSelectorQuery(); - query - .select(`#${canvasId}`) - .node() - .exec((res) => { - if (!res[0] || !res[0].node) reject(new Error('The canvas node may not exist.')); - const canvasNode: HTMLCanvasElement = res[0].node; - const canvasContext: any = canvasNode.getContext(type, options); - // For fallback - const _clearRect = canvasContext.clearRect; - canvasContext.clearRect = (...args) => { - _clearRect.apply(canvasContext, args); - canvasContext.draw(true); - }; - const _fill = canvasContext.fill; - canvasContext.fill = (...args) => { - _fill.apply(canvasContext, args); - canvasContext.draw(true); - }; - const _fillRect = canvasContext.fillRect; - canvasContext.fillRect = (...args) => { - _fillRect.apply(canvasContext, args); - canvasContext.draw(true); - }; - const _fillText = canvasContext.fillText; - canvasContext.fillText = (...args) => { - _fillText.apply(canvasContext, args); - canvasContext.draw(true); - }; - const _stroke = canvasContext.stroke; - canvasContext.stroke = (...args) => { - _stroke.apply(canvasContext, args); - canvasContext.draw(true); - }; - const _strokeRect = canvasContext.strokeRect; - canvasContext.strokeRect = (...args) => { - _strokeRect.apply(canvasContext, args); - canvasContext.draw(true); - }; - // 字节没有该方法 - // const _strokeText = canvasContext.strokeText; - // canvasContext.strokeText = (...args) => { - // _strokeText.apply(canvasContext, args); - // canvasContext.draw(true); - // }; - Object.defineProperty(canvasContext, 'fillStyle', { - get() { - return canvasContext.setFillStyle; - }, - set(value) { - canvasContext.setFillStyle(value); - }, - }); - Object.defineProperty(canvasContext, 'strokeStyle', { - get() { - return canvasContext.setStrokeStyle; - }, - set(value) { - canvasContext.setStrokeStyle(value); - }, - }); - Object.defineProperty(canvasContext, 'fontSize', { - get() { - return canvasContext.setFontSize; - }, - set(value) { - canvasContext.setFontSize(value); - }, - }); - Object.defineProperty(canvasContext, 'globalAlpha', { - get() { - return canvasContext.setGlobalAlpha; - }, - set(value) { - canvasContext.setGlobalAlpha(value); - }, - }); - Object.defineProperty(canvasContext, 'lineWidth', { - get() { - return canvasContext.setLineWidth; - }, - set(value) { - canvasContext.setLineWidth(value); - }, - }); - Object.defineProperty(canvasContext, 'lineCap', { - get() { - return canvasContext.setLineCap; - }, - set(value) { - canvasContext.setLineCap(value); - }, - }); - Object.defineProperty(canvasContext, 'lineJoin', { - get() { - return canvasContext.setLineJoin; - }, - set(value) { - canvasContext.setLineJoin(value); - }, - }); - Object.defineProperty(canvasContext, 'miterLimit', { - get() { - return canvasContext.setMiterLimit; - }, - set(value) { - canvasContext.setMiterLimit(value); - }, - }); - Object.defineProperty(canvasContext, 'textAlign', { - get() { - return canvasContext.setTextAlign; - }, - set(value) { - canvasContext.setTextAlign(value); - }, - }); - Object.defineProperty(canvasContext, 'textBaseLine', { - get() { - return canvasContext.setTextBaseLine; - }, - set(value) { - canvasContext.setTextBaseLine(value); - }, - }); - resolve(canvasContext); + query.select(`#${canvasId}`).node().exec((res) => { + if (!res[0] || !res[0].node) reject(new Error('The canvas node may not exist.')); + const canvasNode: HTMLCanvasElement = res[0].node; + const canvasContext: any = canvasNode.getContext(type, options); // For fallback + + const _clearRect = canvasContext.clearRect; + + canvasContext.clearRect = (...args) => { + _clearRect.apply(canvasContext, args); + + canvasContext.draw(true); + }; + + const _fill = canvasContext.fill; + + canvasContext.fill = (...args) => { + _fill.apply(canvasContext, args); + + canvasContext.draw(true); + }; + + const _fillRect = canvasContext.fillRect; + + canvasContext.fillRect = (...args) => { + _fillRect.apply(canvasContext, args); + + canvasContext.draw(true); + }; + + const _fillText = canvasContext.fillText; + + canvasContext.fillText = (...args) => { + _fillText.apply(canvasContext, args); + + canvasContext.draw(true); + }; + + const _stroke = canvasContext.stroke; + + canvasContext.stroke = (...args) => { + _stroke.apply(canvasContext, args); + + canvasContext.draw(true); + }; + + const _strokeRect = canvasContext.strokeRect; + + canvasContext.strokeRect = (...args) => { + _strokeRect.apply(canvasContext, args); + + canvasContext.draw(true); + }; // 字节没有该方法 + // const _strokeText = canvasContext.strokeText; + // canvasContext.strokeText = (...args) => { + // _strokeText.apply(canvasContext, args); + // canvasContext.draw(true); + // }; + + + Object.defineProperty(canvasContext, 'fillStyle', { + get() { + return canvasContext.setFillStyle; + }, + + set(value) { + canvasContext.setFillStyle(value); + }, + + }); + Object.defineProperty(canvasContext, 'strokeStyle', { + get() { + return canvasContext.setStrokeStyle; + }, + + set(value) { + canvasContext.setStrokeStyle(value); + }, + }); + Object.defineProperty(canvasContext, 'fontSize', { + get() { + return canvasContext.setFontSize; + }, + + set(value) { + canvasContext.setFontSize(value); + }, + + }); + Object.defineProperty(canvasContext, 'globalAlpha', { + get() { + return canvasContext.setGlobalAlpha; + }, + + set(value) { + canvasContext.setGlobalAlpha(value); + }, + + }); + Object.defineProperty(canvasContext, 'lineWidth', { + get() { + return canvasContext.setLineWidth; + }, + + set(value) { + canvasContext.setLineWidth(value); + }, + + }); + Object.defineProperty(canvasContext, 'lineCap', { + get() { + return canvasContext.setLineCap; + }, + + set(value) { + canvasContext.setLineCap(value); + }, + + }); + Object.defineProperty(canvasContext, 'lineJoin', { + get() { + return canvasContext.setLineJoin; + }, + + set(value) { + canvasContext.setLineJoin(value); + }, + + }); + Object.defineProperty(canvasContext, 'miterLimit', { + get() { + return canvasContext.setMiterLimit; + }, + + set(value) { + canvasContext.setMiterLimit(value); + }, + + }); + Object.defineProperty(canvasContext, 'textAlign', { + get() { + return canvasContext.setTextAlign; + }, + + set(value) { + canvasContext.setTextAlign(value); + }, + + }); + Object.defineProperty(canvasContext, 'textBaseLine', { + get() { + return canvasContext.setTextBaseLine; + }, + + set(value) { + canvasContext.setTextBaseLine(value); + }, + + }); + resolve(canvasContext); + }); }); }, CONTAINER_NAME.BYTE); - export default createContext; diff --git a/src/packages/canvas/src/common.ts b/src/packages/canvas/src/common.ts index 631e3635..10c00bb5 100644 --- a/src/packages/canvas/src/common.ts +++ b/src/packages/canvas/src/common.ts @@ -1,9 +1,8 @@ -import { styleIn } from '@utils/styleOptions'; +import { styleIn } from '@uni/utils'; export function normalize(api, containerName) { return (options) => { const afterOptions = styleIn(options, containerName); - return api(afterOptions); }; } diff --git a/src/packages/canvas/src/kuaishou-miniprogram/createContext.ts b/src/packages/canvas/src/kuaishou-miniprogram/createContext.ts index 225f78c5..729b81da 100644 --- a/src/packages/canvas/src/kuaishou-miniprogram/createContext.ts +++ b/src/packages/canvas/src/kuaishou-miniprogram/createContext.ts @@ -1,63 +1,84 @@ +import { CONTAINER_NAME } from '@uni/utils'; import { CanvasContext, Options } from '../types'; import { normalize } from '../common'; -import { CONTAINER_NAME } from '@utils/constant'; - export const createContext = normalize((canvasOptions: Options): Promise => { // 使用微信的 getContext 方法可以获取 CanvasRenderingContext2D,对齐html canvas 2d context - const { canvasId, type = '2d', context = ks, options } = canvasOptions; + const { + canvasId, + type = '2d', + context = ks, + options, + } = canvasOptions; return new Promise((resolve, reject) => { const query = context.createSelectorQuery(); - query - .select(`#${canvasId}`) - .fields({ node: true, size: true }) - .exec((res) => { - if (!res[0] || !res[0].node) reject(new Error('The canvas node may not exist.')); - const canvasNode: HTMLCanvasElement = res[0].node; - const canvasContext: any = canvasNode.getContext(type, options); - // For fallback - // context.draw = function() {}; - - const _clearRect = canvasContext.clearRect; - canvasContext.clearRect = (...args) => { - _clearRect.apply(canvasContext, args); - canvasContext.draw(true); - }; - const _fill = canvasContext.fill; - canvasContext.fill = (...args) => { - _fill.apply(canvasContext, args); - canvasContext.draw(true); - }; - const _fillRect = canvasContext.fillRect; - canvasContext.fillRect = (...args) => { - _fillRect.apply(canvasContext, args); - canvasContext.draw(true); - }; - const _fillText = canvasContext.fillText; - canvasContext.fillText = (...args) => { - _fillText.apply(canvasContext, args); - canvasContext.draw(true); - }; - const _stroke = canvasContext.stroke; - canvasContext.stroke = (...args) => { - _stroke.apply(canvasContext, args); - canvasContext.draw(true); - }; - const _strokeRect = canvasContext.strokeRect; - canvasContext.strokeRect = (...args) => { - _strokeRect.apply(canvasContext, args); - canvasContext.draw(true); - }; - const _strokeText = canvasContext.strokeText; - canvasContext.strokeText = (...args) => { - _strokeText.apply(canvasContext, args); - canvasContext.draw(true); - }; - resolve(canvasContext); - }); - }); -}, CONTAINER_NAME.KWAI); + query.select(`#${canvasId}`).fields({ + node: true, + size: true, + }).exec((res) => { + if (!res[0] || !res[0].node) reject(new Error('The canvas node may not exist.')); + const canvasNode: HTMLCanvasElement = res[0].node; + const canvasContext: any = canvasNode.getContext(type, options); // For fallback + // context.draw = function() {}; + + const _clearRect = canvasContext.clearRect; + + canvasContext.clearRect = (...args) => { + _clearRect.apply(canvasContext, args); + + canvasContext.draw(true); + }; + + const _fill = canvasContext.fill; + + canvasContext.fill = (...args) => { + _fill.apply(canvasContext, args); + + canvasContext.draw(true); + }; + + const _fillRect = canvasContext.fillRect; + + canvasContext.fillRect = (...args) => { + _fillRect.apply(canvasContext, args); + + canvasContext.draw(true); + }; + + const _fillText = canvasContext.fillText; -export default createContext; -// export default () => {}; + canvasContext.fillText = (...args) => { + _fillText.apply(canvasContext, args); + canvasContext.draw(true); + }; + + const _stroke = canvasContext.stroke; + + canvasContext.stroke = (...args) => { + _stroke.apply(canvasContext, args); + + canvasContext.draw(true); + }; + + const _strokeRect = canvasContext.strokeRect; + + canvasContext.strokeRect = (...args) => { + _strokeRect.apply(canvasContext, args); + + canvasContext.draw(true); + }; + + const _strokeText = canvasContext.strokeText; + + canvasContext.strokeText = (...args) => { + _strokeText.apply(canvasContext, args); + + canvasContext.draw(true); + }; + + resolve(canvasContext); + }); + }); +}, CONTAINER_NAME.KWAI); +export default createContext; // export default () => {}; diff --git a/src/packages/canvas/src/web/createContext.ts b/src/packages/canvas/src/web/createContext.ts index 4709819f..da241428 100644 --- a/src/packages/canvas/src/web/createContext.ts +++ b/src/packages/canvas/src/web/createContext.ts @@ -1,19 +1,21 @@ +import { CONTAINER_NAME } from '@uni/utils'; import { CanvasContext, Options } from '../types'; import { normalize } from '../common'; -import { CONTAINER_NAME } from '@utils/constant'; const createContext = normalize((canvasOptions: Options): Promise => { - const { canvasId, type = '2d', options } = canvasOptions; + const { + canvasId, + type = '2d', + options, + } = canvasOptions; return new Promise((resolve, reject) => { - const canvasNode: HTMLCanvasElement = document.getElementById( - canvasId, - ) as HTMLCanvasElement; + const canvasNode: HTMLCanvasElement = (document.getElementById(canvasId) as HTMLCanvasElement); if (!canvasNode) reject(new Error('The canvas node may not exist.')); - const context: CanvasContext = canvasNode.getContext(type, options); - // For fallback + const context: CanvasContext = canvasNode.getContext(type, options); // For fallback + context.draw = function () {}; + resolve(context); }); }, CONTAINER_NAME.WEB); - export default createContext; diff --git a/src/packages/canvas/src/wechat-miniprogram/createContext.ts b/src/packages/canvas/src/wechat-miniprogram/createContext.ts index 87fbb704..dd0f08b3 100644 --- a/src/packages/canvas/src/wechat-miniprogram/createContext.ts +++ b/src/packages/canvas/src/wechat-miniprogram/createContext.ts @@ -1,24 +1,28 @@ +import { CONTAINER_NAME } from '@uni/utils'; import { CanvasContext, Options } from '../types'; import { normalize } from '../common'; -import { CONTAINER_NAME } from '@utils/constant'; export const createContext = normalize((canvasOptions: Options): Promise => { // 使用微信的 getContext 方法可以获取 CanvasRenderingContext2D,对齐html canvas 2d context - const { canvasId, type = '2d', context = wx, options } = canvasOptions; + const { + canvasId, + type = '2d', + context = wx, + options, + } = canvasOptions; return new Promise((resolve, reject) => { const query = context.createSelectorQuery(); - query - .select(`#${canvasId}`) - .fields({ node: true, size: true }) - .exec((res) => { - if (!res[0] || !res[0].node) reject(new Error('The canvas node may not exist.')); - const canvasNode: HTMLCanvasElement = res[0].node; - const canvasContext: CanvasContext = canvasNode.getContext(type, options); - // For fallback - // context.draw = function() {}; - resolve(canvasContext); - }); + query.select(`#${canvasId}`).fields({ + node: true, + size: true, + }).exec((res) => { + if (!res[0] || !res[0].node) reject(new Error('The canvas node may not exist.')); + const canvasNode: HTMLCanvasElement = res[0].node; + const canvasContext: CanvasContext = canvasNode.getContext(type, options); // For fallback + // context.draw = function() {}; + + resolve(canvasContext); + }); }); }, CONTAINER_NAME.WECHAT); - export default createContext; diff --git a/src/packages/utils/CHANGELOG.md b/src/packages/utils/CHANGELOG.md new file mode 100644 index 00000000..e69de29b diff --git a/src/packages/utils/docs/README.en-US.md.c b/src/packages/utils/docs/README.en-US.md.c new file mode 100644 index 00000000..acdced8e --- /dev/null +++ b/src/packages/utils/docs/README.en-US.md.c @@ -0,0 +1,3 @@ +# @uni/utils + +工具函数 \ No newline at end of file diff --git a/src/packages/utils/docs/README.md.c b/src/packages/utils/docs/README.md.c new file mode 100644 index 00000000..acdced8e --- /dev/null +++ b/src/packages/utils/docs/README.md.c @@ -0,0 +1,3 @@ +# @uni/utils + +工具函数 \ No newline at end of file diff --git a/src/packages/utils/src/callPlatformAPI.ts b/src/packages/utils/src/callPlatformAPI.ts new file mode 100644 index 00000000..9bb1de31 --- /dev/null +++ b/src/packages/utils/src/callPlatformAPI.ts @@ -0,0 +1,20 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ +// eslint-disable-next-line import/no-extraneous-dependencies +// @ts-nocheck +import { isDingdingMiniapp, isMiniapp, isWeChatMiniProgram, isWeb, isKuaiShouMiniProgram, isBaiduSmartProgram } from '@uni/env'; + +export default (platformApi: string, ...args: any) => { + if (isWeb) { + return window[platformApi](args); + } else if (isDingdingMiniapp) { + return dd[platformApi](args); + } else if (isMiniapp) { + return my[platformApi](args); + } else if (isWeChatMiniProgram) { + return wx[platformApi](args); + } else if (isKuaiShouMiniProgram) { + return ks[platformApi](args); + } else if (isBaiduSmartProgram) { + return swan[platformApi](args); + } +}; diff --git a/src/packages/utils/src/constant.ts b/src/packages/utils/src/constant.ts new file mode 100644 index 00000000..5b4a0b72 --- /dev/null +++ b/src/packages/utils/src/constant.ts @@ -0,0 +1,9 @@ +export const CONTAINER_NAME = { + WECHAT: 'wechatMiniProgram', + ALIPAY: 'aliMiniApp', + BYTE: 'bytedanceMicroApp', + WEB: 'web', + BAIDU: 'baiduSmartProgram', + KWAI: 'kuaishouMiniProgram', +}; +export const JSONP_SIGN = '__uni_jsonp_handler_sign__'; diff --git a/src/packages/utils/src/event.ts b/src/packages/utils/src/event.ts new file mode 100644 index 00000000..10936b5d --- /dev/null +++ b/src/packages/utils/src/event.ts @@ -0,0 +1,54 @@ +export default class Events { + private events: any; + + constructor() { + this.events = {}; + } + + emit(key: string, params: any) { + if (this.events[key] && this.events[key].size > 0) { + const _queue = new Set(Array.from(this.events[key])); + + _queue.forEach(async (item: any) => { + item.handler(params); + if (item.once) { + this.events[key].delete(item); + } + }); + } + } + + // async _emit(key: string, params: any) { + // if (this.events[key] && this.events[key].length > 0) { + // const item = this.events[key].shift(); + // if (isAsync(item)) { + // await item(params); + // } else { + // item(params); + // } + // this.emit(key, params); + // } + // } + + once(key: string, cb: (val: any) => void) { + const item = { + once: true, + handler: cb, + }; + this.events[key] ? this.events[key].add(item) : (this.events[key] = new Set([item])); + // return () => { + // this.events[key].delete(item); + // }; + } + + register(key: string, cb: (val: any) => void) { + const item = { + once: false, + handler: cb, + }; + this.events[key] ? this.events[key].add(item) : (this.events[key] = new Set([item])); + return () => { + this.events[key].delete(item); + }; + } +} diff --git a/src/packages/utils/src/index.ts b/src/packages/utils/src/index.ts new file mode 100644 index 00000000..5cd58d29 --- /dev/null +++ b/src/packages/utils/src/index.ts @@ -0,0 +1,7 @@ +export * from './callPlatformAPI'; +export * from './constant'; +export * from './event'; +export * from './miniappEnvApp'; +export * from './promisify'; +export * from './styleOptions'; +export * from './tools'; diff --git a/src/packages/utils/src/miniappEnvApp.ts b/src/packages/utils/src/miniappEnvApp.ts new file mode 100644 index 00000000..38d21e73 --- /dev/null +++ b/src/packages/utils/src/miniappEnvApp.ts @@ -0,0 +1,5 @@ + +function isUndef(type: string): boolean { + return type === 'undefined'; +} +export const isDingdingMiniapp = !isUndef(typeof dd) && dd !== null && !isUndef(typeof dd.alert); diff --git a/src/packages/utils/src/promisify.ts b/src/packages/utils/src/promisify.ts new file mode 100644 index 00000000..3f728756 --- /dev/null +++ b/src/packages/utils/src/promisify.ts @@ -0,0 +1,53 @@ +export interface PromisifyArgs { + success?: (args: SuccessArg) => void; + onSuccess?: (args: SuccessArg) => void; + fail?: (args: FailArg) => void; + onFail?: (args: FailArg) => void; +} +export function promisify( + api: (arg: Arg & PromisifyArgs) => void, +) { + return (arg: Arg & PromisifyArgs) => { + return new Promise((resolve, reject) => { + const promisifyArg: any = arg; + + api({ + ...promisifyArg, + success: (res: SuccessArg) => { + if (promisifyArg && typeof promisifyArg.success === 'function') { + promisifyArg.success(res); + } + resolve(res); + }, + onSuccess: (res: SuccessArg) => { + if (promisifyArg && typeof promisifyArg.onSuccess === 'function') { + promisifyArg.onSuccess(res); + } + resolve(res); + }, + fail: (res: FailArg) => { + if (promisifyArg && typeof promisifyArg.fail === 'function') { + promisifyArg.fail(res); + } + reject(res); + }, + onFail: (res: FailArg) => { + if (promisifyArg && typeof promisifyArg.onFail === 'function') { + promisifyArg.onFail(res); + } + reject(res); + }, + complete: (res: SuccessArg | FailArg) => { + if (promisifyArg && typeof promisifyArg.complete === 'function') { + promisifyArg.complete(res); + } + }, + onComplete: (res: SuccessArg | FailArg) => { + if (promisifyArg && typeof promisifyArg.onComplete === 'function') { + promisifyArg.onComplete(res); + } + }, + }); + }); + }; +} diff --git a/src/packages/utils/src/styleOptions.ts b/src/packages/utils/src/styleOptions.ts new file mode 100644 index 00000000..ca6c35cb --- /dev/null +++ b/src/packages/utils/src/styleOptions.ts @@ -0,0 +1,17 @@ +export const styleOut = (output: any, originalInput, originalOutput) => { + return { + ...output, + _original: { + input: { ...originalInput }, // 实际调用 api 方法时传入的参数. 对入参进行 format 之后的结果 + output: { ...originalOutput }, // 实际调用 api 方法时传入的参数. 返回值 format 之前的结果 + }, + }; +}; + +export const styleIn = (options: any, baseName: string) => { + const { _ext = {}, ...rest } = options || {}; + return { + ...rest, + ...(_ext[baseName] || {}), + }; +}; diff --git a/src/packages/utils/src/tools.ts b/src/packages/utils/src/tools.ts new file mode 100644 index 00000000..09cb4839 --- /dev/null +++ b/src/packages/utils/src/tools.ts @@ -0,0 +1,21 @@ +// 比较传入版本1 是否小于传入版本2,如果相等或者大于 都返回false +export const isLessThanVersion = (target, current, splitSign = '.') => { + const targetArr = target.split(splitSign); + const currentArr = current.split(splitSign); + + let res = false; + currentArr.some((i, idx) => { + if (!targetArr[idx]) { + return true; + } + if (i > targetArr[idx]) { + res = true; + return true; + } else if (i < targetArr[idx]) { + res = false; + return true; + } + return false; + }); + return res; +}; diff --git a/tsconfig.json b/tsconfig.json index 7ebf8046..a11dc16f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -68,6 +68,7 @@ "@/*": ["src/*"], // "types/*": ["types/*"], "@utils/*": ["src/utils/*"], + "@uni/utils": ["src/utils"] } }, "include": ["src/packages/**/src", "types/*", "types"], diff --git a/types/@uni/utils.d.ts b/types/@uni/utils.d.ts new file mode 100644 index 00000000..7a3cbc1f --- /dev/null +++ b/types/@uni/utils.d.ts @@ -0,0 +1 @@ +declare module '@uni/utils';