diff --git a/.browserslistrc b/.browserslistrc index 635fdf53ffa..573c97e9e9c 100644 --- a/.browserslistrc +++ b/.browserslistrc @@ -1,2 +1,4 @@ defaults -ie >= 11 \ No newline at end of file +not ie > 0 +not ie_mob > 0 +not dead \ No newline at end of file diff --git a/babel-plugin-expose-private-functions-and-variables.js b/babel-plugin-expose-private-functions-and-variables.js new file mode 100644 index 00000000000..f0807e3397b --- /dev/null +++ b/babel-plugin-expose-private-functions-and-variables.js @@ -0,0 +1,87 @@ +// eslint-disable-next-line no-undef +module.exports = function ({types: t}) { + + function createNestedMemberExpression(identifiers) { + if (identifiers.length === 1) { + return t.identifier(identifiers[0]); + } else { + const [head, ...tail] = identifiers; + return t.memberExpression( + createNestedMemberExpression(tail), + t.identifier(head) + ); + } + } + + return { + visitor: { + Program: { + exit(path) { + let dir = this.file.opts.filename.replace(/-/g, '_').split('/'); + const jsLoc = dir.findIndex(x => x === 'js'), + file = dir[dir.length - 1], + exports = {}; + + // pass if [not in js folder] or [not ts file] or [is global.d.ts] or [is index.ts] + if (jsLoc === -1 || !file.endsWith('ts') || file === 'global.d.ts' || file === 'index.ts') return; + + // simplify whole dir + dir = dir.slice(jsLoc + 1); + dir[dir.length - 1] = file.replace('.ts', ''); + + // sort order for follow-up + dir.unshift('window'); + dir.push('_'); + dir.reverse(); + + // visit all nodes + path.node.body.forEach((node, index) => { + if (t.isVariableDeclaration(node)) { + node.declarations.forEach((declaration) => { + if (t.isIdentifier(declaration.id)) { + exports[declaration.id.name] = declaration.id.name; + } + }); + } else if (t.isFunctionDeclaration(node) && t.isIdentifier(node.id)) { + exports[node.id.name] = node.id.name; + } + }); + + // add check-exist if statements + for (let i = dir.length - 2; i > 0; i--) { + const nestedExpression = createNestedMemberExpression(dir.slice(i)); + path.pushContainer('body', + t.ifStatement( + t.unaryExpression('!', nestedExpression), + t.expressionStatement( + t.assignmentExpression( + '=', + nestedExpression, + t.objectExpression([]) + ) + ) + ) + ); + } + + // export all global variables and functions + path.pushContainer('body', + // window.x.x.x._ = {...} + t.expressionStatement( + t.assignmentExpression( + '=', + createNestedMemberExpression(dir), + t.objectExpression( + Object.entries(exports).map(([k, v]) => { + return t.objectProperty(t.identifier(k), t.identifier(v)); + }) + ) + ) + ) + ); + + } + } + } + }; +}; \ No newline at end of file diff --git a/babel.config.js b/babel.config.js index 1cb9413d5c9..1eae83290a8 100644 --- a/babel.config.js +++ b/babel.config.js @@ -17,6 +17,7 @@ module.exports = function (api) { ["@babel/plugin-proposal-decorators", { "legacy": true }], '@babel/plugin-proposal-class-properties', '@babel/plugin-proposal-object-rest-spread', + './babel-plugin-expose-private-functions-and-variables', ], overrides: [{ test: /[\\/]ext[\\/]//* treat as script for 3rd-party library */, diff --git a/zkdoc/release-note b/zkdoc/release-note index a7e3cf379e6..6edd1d8ac8a 100644 --- a/zkdoc/release-note +++ b/zkdoc/release-note @@ -20,6 +20,7 @@ ZK 10.0.0 ZK-5533: Add all new HTML5 tags in ZK 10 ZHTML ZK-5049: Deprecate org.zkoss.zk.ui.uuidRecycle.disabled in ZK10 ZK-5437: Upgrade WCAG with the lighthouse 10.x detection tools + ZK-4928: expose widget private functions and variables as public ones * Bugs ZK-5089: AfterSizeEvent doesn't return a correct size of a Window component